{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Convolutional Neural Networks\n",
    "(c) Deniz Yuret, 2019\n",
    "* Objectives: See the effect of sparse and shared weights implemented by convolutional networks.\n",
    "* Prerequisites: [MLP models](40.mlp.ipynb), [MNIST](20.mnist.ipynb)\n",
    "* New functions:\n",
    "[conv4](http://denizyuret.github.io/Knet.jl/latest/reference/#Knet.conv4),\n",
    "[pool](http://denizyuret.github.io/Knet.jl/latest/reference/#Knet.pool),\n",
    "[mat](http://denizyuret.github.io/Knet.jl/latest/reference/#Knet.mat)\n",
    "\n",
    "![image](https://github.com/denizyuret/Knet.jl/blob/master/docs/src/images/le_net.png?raw=true)\n",
    "([image source](http://www.dataiku.com/blog/2015/08/18/Deep_Learning.html))\n",
    "\n",
    "To improve the performance further, we can use a convolutional neural networks (CNN). See the [course notes](http://cs231n.github.io/convolutional-networks/) by Andrej Karpathy for a good introduction to CNNs. We will implement the [LeNet](http://yann.lecun.com/exdb/lenet) model which consists of two convolutional layers followed by two fully connected layers. We will describe and use the [conv4](http://denizyuret.github.io/Knet.jl/latest/reference/#Knet.conv4) and [pool](http://denizyuret.github.io/Knet.jl/latest/reference/#Knet.pool) functions provided by Knet for the implementation of convolutional nets.\n",
    "\n",
    "Even though MLPs and CNNs are both universal function approximators and both achieve 0 error on the training set, we will see that a CNN converges a lot faster and generalizes a lot better with less overfitting achieving a 99.5% test accuracy on MNIST. The sparse connectivity and shared weights of a CNN give it an inductive bias appropriate for image features allowing it to learn better with less data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "# Setup display width, load packages, import symbols\n",
    "ENV[\"COLUMNS\"]=72\n",
    "using Pkg; for p in (\"Knet\",\"IterTools\",\"Plots\"); haskey(Pkg.installed(),p) || Pkg.add(p); end\n",
    "using Base.Iterators: flatten\n",
    "using IterTools: ncycle, takenth\n",
    "using Statistics: mean\n",
    "using Knet: Knet, conv4, pool, mat, KnetArray, nll, zeroone, progress, sgd, param, param0, dropout, relu, Data, gpu"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Introduction to convolution"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/latex": [
       "\\begin{verbatim}\n",
       "conv4(w, x; kwargs...)\n",
       "\\end{verbatim}\n",
       "Execute convolutions or cross-correlations using filters specified with \\texttt{w} over tensor \\texttt{x}.\n",
       "\n",
       "Currently KnetArray\\{Float32/64,4/5\\} and Array\\{Float32/64,4\\} are supported as \\texttt{w} and \\texttt{x}.  If \\texttt{w} has dimensions \\texttt{(W1,W2,...,I,O)} and \\texttt{x} has dimensions \\texttt{(X1,X2,...,I,N)}, the result \\texttt{y} will have dimensions \\texttt{(Y1,Y2,...,O,N)} where\n",
       "\n",
       "\\begin{verbatim}\n",
       "Yi=1+floor((Xi+2*padding[i]-Wi)/stride[i])\n",
       "\\end{verbatim}\n",
       "Here \\texttt{I} is the number of input channels, \\texttt{O} is the number of output channels, \\texttt{N} is the number of instances, and \\texttt{Wi,Xi,Yi} are spatial dimensions.  \\texttt{padding} and \\texttt{stride} are keyword arguments that can be specified as a single number (in which case they apply to all dimensions), or an array/tuple with entries for each spatial dimension.\n",
       "\n",
       "\\section{Keywords}\n",
       "\\begin{itemize}\n",
       "\\item \\texttt{padding=0}: the number of extra zeros implicitly concatenated at the start and at the end of each dimension.\n",
       "\n",
       "\n",
       "\\item \\texttt{stride=1}: the number of elements to slide to reach the next filtering window.\n",
       "\n",
       "\n",
       "\\item \\texttt{dilation=1}: dilation factor for each dimension.\n",
       "\n",
       "\n",
       "\\item \\texttt{mode=0}: 0 for convolution and 1 for cross-correlation.\n",
       "\n",
       "\n",
       "\\item \\texttt{alpha=1}: can be used to scale the result.\n",
       "\n",
       "\n",
       "\\item \\texttt{handle}: handle to a previously created cuDNN context. Defaults to a Knet allocated handle.\n",
       "\n",
       "\\end{itemize}\n"
      ],
      "text/markdown": [
       "```\n",
       "conv4(w, x; kwargs...)\n",
       "```\n",
       "\n",
       "Execute convolutions or cross-correlations using filters specified with `w` over tensor `x`.\n",
       "\n",
       "Currently KnetArray{Float32/64,4/5} and Array{Float32/64,4} are supported as `w` and `x`.  If `w` has dimensions `(W1,W2,...,I,O)` and `x` has dimensions `(X1,X2,...,I,N)`, the result `y` will have dimensions `(Y1,Y2,...,O,N)` where\n",
       "\n",
       "```\n",
       "Yi=1+floor((Xi+2*padding[i]-Wi)/stride[i])\n",
       "```\n",
       "\n",
       "Here `I` is the number of input channels, `O` is the number of output channels, `N` is the number of instances, and `Wi,Xi,Yi` are spatial dimensions.  `padding` and `stride` are keyword arguments that can be specified as a single number (in which case they apply to all dimensions), or an array/tuple with entries for each spatial dimension.\n",
       "\n",
       "# Keywords\n",
       "\n",
       "  * `padding=0`: the number of extra zeros implicitly concatenated at the start and at the end of each dimension.\n",
       "  * `stride=1`: the number of elements to slide to reach the next filtering window.\n",
       "  * `dilation=1`: dilation factor for each dimension.\n",
       "  * `mode=0`: 0 for convolution and 1 for cross-correlation.\n",
       "  * `alpha=1`: can be used to scale the result.\n",
       "  * `handle`: handle to a previously created cuDNN context. Defaults to a Knet allocated handle.\n"
      ],
      "text/plain": [
       "\u001b[36m  conv4(w, x; kwargs...)\u001b[39m\n",
       "\n",
       "  Execute convolutions or cross-correlations using filters specified\n",
       "  with \u001b[36mw\u001b[39m over tensor \u001b[36mx\u001b[39m.\n",
       "\n",
       "  Currently KnetArray{Float32/64,4/5} and Array{Float32/64,4} are\n",
       "  supported as \u001b[36mw\u001b[39m and \u001b[36mx\u001b[39m. If \u001b[36mw\u001b[39m has dimensions \u001b[36m(W1,W2,...,I,O)\u001b[39m and \u001b[36mx\u001b[39m has\n",
       "  dimensions \u001b[36m(X1,X2,...,I,N)\u001b[39m, the result \u001b[36my\u001b[39m will have dimensions\n",
       "  \u001b[36m(Y1,Y2,...,O,N)\u001b[39m where\n",
       "\n",
       "\u001b[36m  Yi=1+floor((Xi+2*padding[i]-Wi)/stride[i])\u001b[39m\n",
       "\n",
       "  Here \u001b[36mI\u001b[39m is the number of input channels, \u001b[36mO\u001b[39m is the number of output\n",
       "  channels, \u001b[36mN\u001b[39m is the number of instances, and \u001b[36mWi,Xi,Yi\u001b[39m are spatial\n",
       "  dimensions. \u001b[36mpadding\u001b[39m and \u001b[36mstride\u001b[39m are keyword arguments that can be\n",
       "  specified as a single number (in which case they apply to all\n",
       "  dimensions), or an array/tuple with entries for each spatial\n",
       "  dimension.\n",
       "\n",
       "\u001b[1m  Keywords\u001b[22m\n",
       "\u001b[1m  ≡≡≡≡≡≡≡≡≡≡\u001b[22m\n",
       "\n",
       "    •    \u001b[36mpadding=0\u001b[39m: the number of extra zeros implicitly\n",
       "        concatenated at the start and at the end of each\n",
       "        dimension.\n",
       "\n",
       "    •    \u001b[36mstride=1\u001b[39m: the number of elements to slide to reach the\n",
       "        next filtering window.\n",
       "\n",
       "    •    \u001b[36mdilation=1\u001b[39m: dilation factor for each dimension.\n",
       "\n",
       "    •    \u001b[36mmode=0\u001b[39m: 0 for convolution and 1 for cross-correlation.\n",
       "\n",
       "    •    \u001b[36malpha=1\u001b[39m: can be used to scale the result.\n",
       "\n",
       "    •    \u001b[36mhandle\u001b[39m: handle to a previously created cuDNN context.\n",
       "        Defaults to a Knet allocated handle."
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Convolution operator in Knet\n",
    "@doc conv4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "w = [1.0; 2.0; 3.0]\n",
      "x = [1.0; 2.0; 3.0; 4.0; 5.0; 6.0; 7.0]\n",
      "y = conv4(w, x) = [10.0; 16.0; 22.0; 28.0; 34.0]\n"
     ]
    }
   ],
   "source": [
    "# Convolution in 1-D\n",
    "w = reshape([1.0,2.0,3.0], (3,1,1,1)); @show w\n",
    "x = reshape([1.0:7.0...], (7,1,1,1)); @show x\n",
    "@show y = conv4(w, x);  # size Y = X - W + 1 = 5 by default"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "w = [1.0; 2.0; 3.0]\n",
      "x = [1.0; 2.0; 3.0; 4.0; 5.0; 6.0; 7.0]\n",
      "y2 = conv4(w, x, padding=(1, 0)) = [4.0; 10.0; 16.0; 22.0; 28.0; 34.0; 32.0]\n"
     ]
    }
   ],
   "source": [
    "# Padding\n",
    "w = reshape([1.0,2.0,3.0], (3,1,1,1)); @show w\n",
    "x = reshape([1.0:7.0...], (7,1,1,1)); @show x\n",
    "@show y2 = conv4(w, x, padding=(1,0));  # size Y = X + 2P - W + 1 = 7 with padding=1\n",
    "# To preserve input size (Y=X) for a given W, what padding P should we use?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "w = [1.0; 2.0; 3.0]\n",
      "x = [1.0; 2.0; 3.0; 4.0; 5.0; 6.0; 7.0]\n",
      "y3 = conv4(w, x; padding=(1, 0), stride=3) = [4.0; 22.0; 32.0]\n"
     ]
    }
   ],
   "source": [
    "# Stride\n",
    "w = reshape([1.0,2.0,3.0], (3,1,1,1)); @show w\n",
    "x = reshape([1.0:7.0...], (7,1,1,1)); @show x\n",
    "@show y3 = conv4(w, x; padding=(1,0), stride=3);  # size Y = 1 + floor((X+2P-W)/S)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "w = [1.0; 2.0; 3.0]\n",
      "x = [1.0; 2.0; 3.0; 4.0; 5.0; 6.0; 7.0]\n",
      "y4 = conv4(w, x, mode=0) = [10.0; 16.0; 22.0; 28.0; 34.0]\n",
      "y5 = conv4(w, x, mode=1) = [14.0; 20.0; 26.0; 32.0; 38.0]\n"
     ]
    }
   ],
   "source": [
    "# Mode\n",
    "w = reshape([1.0,2.0,3.0], (3,1,1,1)); @show w\n",
    "x = reshape([1.0:7.0...], (7,1,1,1)); @show x\n",
    "@show y4 = conv4(w, x, mode=0);  # Default mode (convolution) inverts w\n",
    "@show y5 = conv4(w, x, mode=1);  # mode=1 (cross-correlation) does not invert w"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3×3×1×1 Array{Float64,4}:\n",
       "[:, :, 1, 1] =\n",
       " 1.0  4.0  7.0\n",
       " 2.0  5.0  8.0\n",
       " 3.0  6.0  9.0"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Convolution in more dimensions\n",
    "x = reshape([1.0:9.0...], (3,3,1,1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2×2×1×1 Array{Float64,4}:\n",
       "[:, :, 1, 1] =\n",
       " 1.0  3.0\n",
       " 2.0  4.0"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "w = reshape([1.0:4.0...], (2,2,1,1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2×2×1×1 Array{Float64,4}:\n",
       "[:, :, 1, 1] =\n",
       " 23.0  53.0\n",
       " 33.0  63.0"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y = conv4(w, x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3×3×2×1 Array{Float64,4}:\n",
       "[:, :, 1, 1] =\n",
       " 1.0  4.0  7.0\n",
       " 2.0  5.0  8.0\n",
       " 3.0  6.0  9.0\n",
       "\n",
       "[:, :, 2, 1] =\n",
       " 10.0  13.0  16.0\n",
       " 11.0  14.0  17.0\n",
       " 12.0  15.0  18.0"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Convolution with multiple channels, filters, and instances\n",
    "# size X = [X1,X2,...,Xd,Cx,N] where d is the number of dimensions, Cx is channels, N is instances\n",
    "x = reshape([1.0:18.0...], (3,3,2,1)) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "# size W = [W1,W2,...,Wd,Cx,Cy] where d is the number of dimensions, Cx is input channels, Cy is output channels\n",
    "w = reshape([1.0:24.0...], (2,2,2,3));"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2×2×3×1 Array{Float64,4}:\n",
       "[:, :, 1, 1] =\n",
       " 328.0  436.0\n",
       " 364.0  472.0\n",
       "\n",
       "[:, :, 2, 1] =\n",
       " 808.0  1108.0\n",
       " 908.0  1208.0\n",
       "\n",
       "[:, :, 3, 1] =\n",
       " 1288.0  1780.0\n",
       " 1452.0  1944.0"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# size Y = [Y1,Y2,...,Yd,Cy,N]  where Yi = 1 + floor((Xi+2Pi-Wi)/Si), Cy is channels, N is instances\n",
    "y = conv4(w,x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "See http://cs231n.github.io/assets/conv-demo/index.html for an animated example."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Introduction to Pooling"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/latex": [
       "\\begin{verbatim}\n",
       "pool(x; kwargs...)\n",
       "\\end{verbatim}\n",
       "Compute pooling of input values (i.e., the maximum or average of several adjacent values) to produce an output with smaller height and/or width.\n",
       "\n",
       "Currently 4 or 5 dimensional KnetArrays with \\texttt{Float32} or \\texttt{Float64} entries are supported.  If \\texttt{x} has dimensions \\texttt{(X1,X2,...,I,N)}, the result \\texttt{y} will have dimensions \\texttt{(Y1,Y2,...,I,N)} where\n",
       "\n",
       "\\begin{verbatim}\n",
       "Yi=1+floor((Xi+2*padding[i]-window[i])/stride[i])\n",
       "\\end{verbatim}\n",
       "Here \\texttt{I} is the number of input channels, \\texttt{N} is the number of instances, and \\texttt{Xi,Yi} are spatial dimensions.  \\texttt{window}, \\texttt{padding} and \\texttt{stride} are keyword arguments that can be specified as a single number (in which case they apply to all dimensions), or an array/tuple with entries for each spatial dimension.\n",
       "\n",
       "\\section{Keywords:}\n",
       "\\begin{itemize}\n",
       "\\item \\texttt{window=2}: the pooling window size for each dimension.\n",
       "\n",
       "\n",
       "\\item \\texttt{padding=0}: the number of extra zeros implicitly concatenated at the start and at the end of each dimension.\n",
       "\n",
       "\n",
       "\\item \\texttt{stride=window}: the number of elements to slide to reach the next pooling window.\n",
       "\n",
       "\n",
       "\\item \\texttt{mode=0}: 0 for max, 1 for average including padded values, 2 for average excluding padded values.\n",
       "\n",
       "\n",
       "\\item \\texttt{maxpoolingNanOpt=0}: Nan numbers are not propagated if 0, they are propagated if 1.\n",
       "\n",
       "\n",
       "\\item \\texttt{alpha=1}: can be used to scale the result.\n",
       "\n",
       "\n",
       "\\item \\texttt{handle}: Handle to a previously created cuDNN context. Defaults to a Knet allocated handle.\n",
       "\n",
       "\\end{itemize}\n"
      ],
      "text/markdown": [
       "```\n",
       "pool(x; kwargs...)\n",
       "```\n",
       "\n",
       "Compute pooling of input values (i.e., the maximum or average of several adjacent values) to produce an output with smaller height and/or width.\n",
       "\n",
       "Currently 4 or 5 dimensional KnetArrays with `Float32` or `Float64` entries are supported.  If `x` has dimensions `(X1,X2,...,I,N)`, the result `y` will have dimensions `(Y1,Y2,...,I,N)` where\n",
       "\n",
       "```\n",
       "Yi=1+floor((Xi+2*padding[i]-window[i])/stride[i])\n",
       "```\n",
       "\n",
       "Here `I` is the number of input channels, `N` is the number of instances, and `Xi,Yi` are spatial dimensions.  `window`, `padding` and `stride` are keyword arguments that can be specified as a single number (in which case they apply to all dimensions), or an array/tuple with entries for each spatial dimension.\n",
       "\n",
       "# Keywords:\n",
       "\n",
       "  * `window=2`: the pooling window size for each dimension.\n",
       "  * `padding=0`: the number of extra zeros implicitly concatenated at the start and at the end of each dimension.\n",
       "  * `stride=window`: the number of elements to slide to reach the next pooling window.\n",
       "  * `mode=0`: 0 for max, 1 for average including padded values, 2 for average excluding padded values.\n",
       "  * `maxpoolingNanOpt=0`: Nan numbers are not propagated if 0, they are propagated if 1.\n",
       "  * `alpha=1`: can be used to scale the result.\n",
       "  * `handle`: Handle to a previously created cuDNN context. Defaults to a Knet allocated handle.\n"
      ],
      "text/plain": [
       "\u001b[36m  pool(x; kwargs...)\u001b[39m\n",
       "\n",
       "  Compute pooling of input values (i.e., the maximum or average of\n",
       "  several adjacent values) to produce an output with smaller height\n",
       "  and/or width.\n",
       "\n",
       "  Currently 4 or 5 dimensional KnetArrays with \u001b[36mFloat32\u001b[39m or \u001b[36mFloat64\u001b[39m\n",
       "  entries are supported. If \u001b[36mx\u001b[39m has dimensions \u001b[36m(X1,X2,...,I,N)\u001b[39m, the\n",
       "  result \u001b[36my\u001b[39m will have dimensions \u001b[36m(Y1,Y2,...,I,N)\u001b[39m where\n",
       "\n",
       "\u001b[36m  Yi=1+floor((Xi+2*padding[i]-window[i])/stride[i])\u001b[39m\n",
       "\n",
       "  Here \u001b[36mI\u001b[39m is the number of input channels, \u001b[36mN\u001b[39m is the number of\n",
       "  instances, and \u001b[36mXi,Yi\u001b[39m are spatial dimensions. \u001b[36mwindow\u001b[39m, \u001b[36mpadding\u001b[39m and\n",
       "  \u001b[36mstride\u001b[39m are keyword arguments that can be specified as a single\n",
       "  number (in which case they apply to all dimensions), or an\n",
       "  array/tuple with entries for each spatial dimension.\n",
       "\n",
       "\u001b[1m  Keywords:\u001b[22m\n",
       "\u001b[1m  ≡≡≡≡≡≡≡≡≡≡≡\u001b[22m\n",
       "\n",
       "    •    \u001b[36mwindow=2\u001b[39m: the pooling window size for each dimension.\n",
       "\n",
       "    •    \u001b[36mpadding=0\u001b[39m: the number of extra zeros implicitly\n",
       "        concatenated at the start and at the end of each\n",
       "        dimension.\n",
       "\n",
       "    •    \u001b[36mstride=window\u001b[39m: the number of elements to slide to reach\n",
       "        the next pooling window.\n",
       "\n",
       "    •    \u001b[36mmode=0\u001b[39m: 0 for max, 1 for average including padded values,\n",
       "        2 for average excluding padded values.\n",
       "\n",
       "    •    \u001b[36mmaxpoolingNanOpt=0\u001b[39m: Nan numbers are not propagated if 0,\n",
       "        they are propagated if 1.\n",
       "\n",
       "    •    \u001b[36malpha=1\u001b[39m: can be used to scale the result.\n",
       "\n",
       "    •    \u001b[36mhandle\u001b[39m: Handle to a previously created cuDNN context.\n",
       "        Defaults to a Knet allocated handle."
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Pooling operator in Knet\n",
    "@doc pool"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x = [1.0; 2.0; 3.0; 4.0; 5.0; 6.0]\n",
      "pool(x; window=(2, 1)) = [2.0; 4.0; 6.0]\n"
     ]
    }
   ],
   "source": [
    "# 1-D pooling example\n",
    "x = reshape([1.0:6.0...], (6,1,1,1)); @show x\n",
    "@show pool(x; window=(2,1));"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x = [1.0; 2.0; 3.0; 4.0; 5.0; 6.0]\n",
      "pool(x; window=(3, 1)) = [3.0; 6.0]\n"
     ]
    }
   ],
   "source": [
    "# Window size\n",
    "x = reshape([1.0:6.0...], (6,1,1,1)); @show x\n",
    "@show pool(x; window=(3,1));  # size Y = floor(X/W)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x = [1.0; 2.0; 3.0; 4.0; 5.0; 6.0]\n",
      "pool(x; window=(2, 1), padding=(1, 0)) = [1.0; 3.0; 5.0; 6.0]\n"
     ]
    }
   ],
   "source": [
    "# Padding\n",
    "x = reshape([1.0:6.0...], (6,1,1,1)); @show x\n",
    "@show pool(x; window=(2,1), padding=(1,0));  # size Y = floor((X+2P)/W)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x = [1.0; 2.0; 3.0; 4.0; 5.0; 6.0; 7.0; 8.0; 9.0; 10.0]\n",
      "pool(x; window=(2, 1), stride=4) = [2.0; 6.0; 10.0]\n"
     ]
    }
   ],
   "source": [
    "# Stride\n",
    "x = reshape([1.0:10.0...], (10,1,1,1)); @show x\n",
    "@show pool(x; window=(2,1), stride=4);  # size Y = 1 + floor((X+2P-W)/S)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x = K64(6,1,1,1)[1.0⋯]\n",
      "pool(x; padding=(1, 0), mode=0) = K64(4,1,1,1)[1.0⋯]\n",
      "pool(x; padding=(1, 0), mode=1) = K64(4,1,1,1)[0.5⋯]\n",
      "pool(x; padding=(1, 0), mode=2) = K64(4,1,1,1)[1.0⋯]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "4×1×1×1 KnetArray{Float64,4}:\n",
       "[:, :, 1, 1] =\n",
       " 1.0\n",
       " 2.5\n",
       " 4.5\n",
       " 6.0"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Mode (using KnetArray here; not all modes are implemented on the CPU)\n",
    "if gpu() >= 0\n",
    "    x = KnetArray(reshape([1.0:6.0...], (6,1,1,1))); @show x\n",
    "    @show pool(x; padding=(1,0), mode=0)  # max pooling\n",
    "    @show pool(x; padding=(1,0), mode=1)  # avg pooling\n",
    "    @show pool(x; padding=(1,0), mode=2); # avg pooling excluding padded values (is not implemented on CPU)\n",
    "end"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4×4×1×1 Array{Float64,4}:\n",
       "[:, :, 1, 1] =\n",
       " 1.0  5.0   9.0  13.0\n",
       " 2.0  6.0  10.0  14.0\n",
       " 3.0  7.0  11.0  15.0\n",
       " 4.0  8.0  12.0  16.0"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# More dimensions\n",
    "x = reshape([1.0:16.0...], (4,4,1,1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2×2×1×1 Array{Float64,4}:\n",
       "[:, :, 1, 1] =\n",
       " 6.0  14.0\n",
       " 8.0  16.0"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pool(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4×4×2×1 Array{Float64,4}:\n",
       "[:, :, 1, 1] =\n",
       " 1.0  5.0   9.0  13.0\n",
       " 2.0  6.0  10.0  14.0\n",
       " 3.0  7.0  11.0  15.0\n",
       " 4.0  8.0  12.0  16.0\n",
       "\n",
       "[:, :, 2, 1] =\n",
       " 17.0  21.0  25.0  29.0\n",
       " 18.0  22.0  26.0  30.0\n",
       " 19.0  23.0  27.0  31.0\n",
       " 20.0  24.0  28.0  32.0"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Multiple channels and instances\n",
    "x = reshape([1.0:32.0...], (4,4,2,1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2×2×2×1 Array{Float64,4}:\n",
       "[:, :, 1, 1] =\n",
       " 6.0  14.0\n",
       " 8.0  16.0\n",
       "\n",
       "[:, :, 2, 1] =\n",
       " 22.0  30.0\n",
       " 24.0  32.0"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# each channel and each instance is pooled separately\n",
    "pool(x)  # size Y = (Y1,...,Yd,Cx,N) where Yi are spatial dims, Cx and N are identical to input X"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Experiment setup"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "┌ Info: Loading MNIST...\n",
      "└ @ Main /kuacc/users/dyuret/.julia/dev/Knet/data/mnist.jl:33\n"
     ]
    }
   ],
   "source": [
    "# Load data (see mnist.ipynb)\n",
    "include(Knet.dir(\"data\",\"mnist.jl\"))  # Load data\n",
    "dtrn,dtst = mnistdata();              # dtrn and dtst = [ (x1,y1), (x2,y2), ... ] where xi,yi are minibatches of 100"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "28×28×1×100 KnetArray{Float32,4}\n",
      "100-element Array{UInt8,1}\n"
     ]
    }
   ],
   "source": [
    "(x,y) = first(dtst)\n",
    "println.(summary.((x,y)));"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "trainresults (generic function with 1 method)"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# For running experiments\n",
    "function trainresults(file,model; o...)\n",
    "    if (print(\"Train from scratch? \"); readline()[1]=='y')\n",
    "        r = ((model(dtrn), model(dtst), zeroone(model,dtrn), zeroone(model,dtst))\n",
    "             for x in takenth(progress(sgd(model,ncycle(dtrn,100))),length(dtrn)))\n",
    "        r = reshape(collect(Float32,flatten(r)),(4,:))\n",
    "        Knet.save(file,\"results\",r)\n",
    "        Knet.gc() # To save gpu memory\n",
    "    else\n",
    "        isfile(file) || download(\"http://people.csail.mit.edu/deniz/models/tutorial/$file\",file)\n",
    "        r = Knet.load(file,\"results\")\n",
    "    end\n",
    "    println(minimum(r,dims=2))\n",
    "    return r\n",
    "end"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## A convolutional neural network model for MNIST"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Conv"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Define a convolutional layer:\n",
    "struct Conv; w; b; f; p; end\n",
    "(c::Conv)(x) = c.f.(pool(conv4(c.w, dropout(x,c.p)) .+ c.b))\n",
    "Conv(w1::Int,w2::Int,cx::Int,cy::Int,f=relu;pdrop=0) = Conv(param(w1,w2,cx,cy), param0(1,1,cy,1), f, pdrop)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Dense"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Redefine dense layer (See mlp.ipynb):\n",
    "struct Dense; w; b; f; p; end\n",
    "(d::Dense)(x) = d.f.(d.w * mat(dropout(x,d.p)) .+ d.b) # mat reshapes 4-D tensor to 2-D matrix so we can use matmul\n",
    "Dense(i::Int,o::Int,f=relu;pdrop=0) = Dense(param(o,i), param0(o), f, pdrop)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "# Let's define a chain of layers\n",
    "struct Chain\n",
    "    layers\n",
    "    Chain(layers...) = new(layers)\n",
    "end\n",
    "(c::Chain)(x) = (for l in c.layers; x = l(x); end; x)\n",
    "(c::Chain)(x,y) = nll(c(x),y)\n",
    "(c::Chain)(d::Data) = mean(c(x,y) for (x,y) in d)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "scrolled": true,
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4-element Array{String,1}:\n",
       " \"5×5×1×20 AutoGrad.Param{KnetArray{Float32,4}}\" \n",
       " \"5×5×20×50 AutoGrad.Param{KnetArray{Float32,4}}\"\n",
       " \"500×800 AutoGrad.Param{KnetArray{Float32,2}}\"  \n",
       " \"10×500 AutoGrad.Param{KnetArray{Float32,2}}\"   "
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lenet =   Chain(Conv(5,5,1,20), \n",
    "                Conv(5,5,20,50), \n",
    "                Dense(800,500,pdrop=0.3), \n",
    "                Dense(500,10,identity,pdrop=0.3))\n",
    "summary.(l.w for l in lenet.layers)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2.2864733f0"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lenet(x,y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## CNN vs MLP"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train from scratch? stdin> n\n",
      "Float32[0.00014203013; 0.018552596; 0.0; 0.0041]\n"
     ]
    }
   ],
   "source": [
    "# 1.08e-02  100.00%┣████████████████▉┫ 60000/60000 [03:50/03:50, 260.67i/s]\n",
    "# [0.000135032; 0.0196918; 0.0; 0.0053]\n",
    "cnn = trainresults(\"cnn113.jld2\", lenet);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "mlp = Knet.load(\"mlp113f.jld2\",\"results\");"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "using Plots; default(fmt=:png,ls=:auto)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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zre9PYnQk89o/2u49aBLMTExr7/++vr169etWycQCAYNGrRw4cJG53Tr1m3ChAk//fSTh+WewDCMzWbTNO31P3g/3SPMzMzMzc2laTo3NzcrKwshlJeX57I8NTX1999/N5vNu3fv7tChQ/urpkm66njttqv/c9469g8xGyn52PWWFlpzYselcpLT9XsDdDwVACCsvP76699//339boINtxWsP05PT1+zZs1vv/32448/LlmyRCQSoSYbEC5evNjlVoX15YHDT4lw/vz5hYWFc+bMKS4udrbzli5d2lz58ePHZ86c+ddffz399NPtr5rg4w4L+XCfB6IFUS2f7T19orDTao97sWc+aTzyuyX/lE9DAgAA0JSfukZFIlGjDY6d3wialiclJb3//vterJrFJSgbvf7014MTB3aPTvfild0bpMAOq+jZnrVpCbFUvuAlzZevKZ56n5ApfBwaAACA20J/ZRmEIZyNzes8w59ZECGUpcQOV7ViPBgntZtoxDTL1dO+CwkAAEBTfmoRMovFJ4qrS8WUKCki3m+V3iXHrmhpgx2JPL6nKx413ZcRAQAAcCEMWoQIiZP5RouZpv06xY1LoF4y7ITHtwkBAAAwIiwSYfqCpAFdeydHJvq53tb2jtajDHUOTYXX4wEAgHYKsQ2YnMIiESKEfivYuf1arp8rHaTAjlS1pRlqPP6HftcPXo8HAABa5HIbJmdh6G3A5BQuiXBSx7ETOo7xc6WDlfhhFU21vk0oHHiP+dxhymTwQVAAAOCOy22YnIWhtwGTU1gMlindpaoR16hiK7NTRvizXgUfybjYFS3dVdK6VZRwYQQ3/S7T6X2iIRN9FBsAIDDVXNRTjju+PgtjuXwFFyFk0zlIC1l/rCtqvMCsvLsYIzCEkK7IJE7i1x/bdHcsmcaNZIlTXK/JV78N05QpU7744guHwzF//nxnFly8eLHNZmu44JdzAybn8axZsw4cOLBly5bZs2c3vGBz5QElLBJh4j0KvolQ0jL/V52lwA5VtToRIoREWePrtn4CiRCAcKO5oCPNd7SfMEziTH7WOrutzl5/rD7TeL9xaRcRQWAIIe11ozCWV39sLLtjAwBRsqC5RLhixYrs7Oz169dPnjx5zZo1bDZ77dq1q1atchaOHz/e/QZM//znP7OyspKSklosDyhhkQgRQiKOsMaPm9TXG6TE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rg4DIULeNGbMGG8nAaGuDgMhQh1RYWHh7Nmz165d+8EHH2RmZur1+smTJ9evSt2zZ8+6deuKi4vDw8OnTJnieSWkx4EDB7799tuioqKoqKgHH3zQs8rlcn344YdpaWlGozE+Pn7evHlRUVEAUFpa+tlnn2VkZLhcrvj4+CeffLJHjx7tfLIIeRd2lkGo41qwYEFQUNDTTz+dkJCwfPnyvXv3epbv3bt36dKlKSkp8+fPT05OXrp06b59+zyrjhw5smTJkr59+77wwgvR0dFLly71tDj+4x//oJTOmzfvqaeeMpvNb7/9NgBQShcuXGixWGbOnPnUU0/JZLLFixfjSw1RV4MlQoS8qdH+MnWdZe64445Zs2YBwOjRo1Uq1dq1a++8804AWLNmzfTp0x999FEAGDFihEqlWrNmzR133AEAq1evnjlz5rRp0wBg+PDhJSUl27dvB4BBgwY988wznt2Ghoa+8MILAGA0GouKit5+++2AgADPrj7++GO73e7j49P2p45QR4GBECFv+vzzz5tZe9ddd9X9fvfdd3///fdut5tSmp+f//rrr9etGjt27DfffON2uwHgwoULr7zyimc5IeSNN97gef6BBx6oX3eq0+k8r53RarV+fn5vvvnmpEmT+vTpo9Fo5s+f36rnh9AtAAMhQt7U/JCG+u/dDgoKAgCTyeT501OGq79Zo6uUSqXnF51O13D/MpnsnXfe+frrr9966y2n05mSkjJnzpykpKQbOxeEblHYRohQx2U0Gq/6XafTeUJaVVVV3SrP7zqdzs/PDwDMZnPdqtLS0oyMDAAghDR6iMjIyEWLFv3www8rVqzQarULFy70lCwR6jowECLUcW3btq3u959//jkyMlIul8vl8sjIyPqD7rdv3x4VFSWXyxUKRURExO7du+tWffDBB6tWrWpq/2azecaMGTabTSKRJCUlPfvss1artba2to1OB6GOCatGEfKmnTt3Nro8Pj4eAH788UebzZaUlHT69OktW7YsXLjQs3b69OlvvvmmzWZLTEzMzs7euHFjXbvgjBkzli1bZrPZ4uLi0tPT09LSFi1a5CkUNqTValmWffXVV8eOHUsp3b17d0RERP2aVYS6AuJpM0cItb+mplgDgM8//3z27NmffvrpRx99dOHCBb1eP2XKlHHjxtVt8Ouvv65bt66kpCQ0NHTq1Kme3qQeu3btWr9+fUlJSUhIyJQpU8aOHXvVFGueQYqeMmV+fv6///3v8+fPA0BycvKTTz4ZGhraVieMUIeEgRChjqh+rEIItSlsI0QIIdSlYSBECCHUpWHVKEIdkdPpzM3NTU5O9nZCEOr8MBAihBDq0rBqFCGEUJeGgRAhhFCXhoEQIYRQl4aBECGEUJeGgRAhhFCX9v9grl+Z+0mwVgAAAABJRU5ErkJggg=="
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Comparison to MLP shows faster convergence, better generalization\n",
    "plot([mlp[1,:], mlp[2,:], cnn[1,:], cnn[2,:]],ylim=(0.0,0.1),\n",
    "     labels=[:trnMLP :tstMLP :trnCNN :tstCNN],xlabel=\"Epochs\",ylabel=\"Loss\")  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "scrolled": false,
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAlgAAAGQCAIAAAD9V4nPAAAABmJLR0QA/wD/AP+gvaeTAAAgAElEQVR4nOzdd3gU1doA8Hdmtrdsskk2jRQSSkIPHURAjYiCNKUIiBW9etWrcr167fohYr3XjhVRUUCKBSUghCqCVKkhlJCE9La9zsz3x+YuIdnsbjbb5/09/DF7ZuacNyFP3pyZUwiWZQEhhBDiKjLUASCEEEKhhIkQIYQQp2EiRAghxGmYCBFCCHEaJkKEEEKchokQIYQQp2EiRAghxGm8ILSh0+mWLl164sSJvn37PvHEE3K53E35/v37ly1b1tDQoFKp/va3vw0ZMiQIESKEEOKsYPQIV61apVarV61alZiYuHr1ajflNE2/8sorDz744Lp16xYsWPDGG28EITyEEEJcFoxEuHv37ilTpggEgilTpuzatctNOU3TTz311KBBg8xmM5/Pl0qlQQgPIYQQlwXj0WhDQ4NarQYAtVrd2NjoplwgEAwfPtxkMk2ZMgUA/vOf/7is8Isvvli3bh1BEM4SoVC4cuVKx7HNZuPz+QH7asBohyoTZLc83wWmuQ5EUlIkCVyLEYFlWZqmebxg/ESh1miaJgiCJPF9f7AF+lcNcqmzv2p4PF7rZOH6mi5H5RnLso44WJZlGMZjuVgs/vHHH9evX//BBx+8//777St87rnnnnzyycTERGcJRVE0TTuO6+rqEhMTPX7lPjvaQDz+J7FrYkvA+k1f8zJ6i4ZdH6DmIoXFYjEajbGxsaEOhHM0Gg2fz5dIuP6nWPDV19fHx8fjnyBBZrVa9Xp9XFycl9dTFBUWiVClUtXW1qalpTl+btyUV1VV/fzzz/fee69YLJ44ceK3337rOmge78Ybb8zKynJ5VigUikSiwCXCniq4aLCJRCLHR7p7H2v5GedHziIIgqZp/D4En8Vi4fP5+J0PPsevGkyEQUaSpM1m8+8PfDD+C0eMGFFYWMiybGFh4ahRowDg6NGjLstVKtXGjRuPHTvGsuz27dtzcnKCEF5nqcVgsIPe1vJRkNnbWno6pBEhhBDyXTAS4fz588+fPz9nzpzS0tK5c+cCwKJFi1yWCwSCF1988YMPPpg+fXpRUdGjjz4ahPA6iwDIkBEX9S3bV/GTs+xNtYxJH9qoEEII+SYYj0ZlMtnixYtbl2zZssVlOQAMGDDgww8/DEJUXZEph1I99HG8DiNJQbcca9kZUa/8EIeFEEKo8/Dpti+y5MQF3eUNjQUZudaLxSGMByGEkM9wsLsvMmVEaatEqLh+DsEXhDAehBBCPsMeoS8cj0adCKEYSCp04SCEEPIdJkJftHk0ihBCKHJhIvRFm0ejDqzVHJJgEEIIdUX0J8LvT/9kpa3+rTNeBDYGNK1q1e/6UfPjp/5tBSGEUBBEfyJMlqkJ8P8qMxkyolTfauBot54WnFaPEEIRKPoT4UB1XyoAI1my5Fc8HeWnZdtrK/DpKEIIRZzoT4QfHvqi2lDr92oz5VCqu/yR4PH5KZnWshK/N4QQQiigoj8RLhr+YIosye/VZl75aBQARD0GWUoO+70hhBBCARX9ifCr46vPNp33e7VZcrigu6JE2CvffPqQ3xtCCCEUUNG/ssxN2QUSvv+3asuUE6U6pnWJICs3dvY//N4QQgihgIr+RKi16hlgRTyhf6vt3m5OPUHx+MmZ/m0FIYRQoEX/o9EybUWdsd7v1cYIgCSg0eL3ihFCCAVV9PcIr+42MkA1OxZaixNeOUmRYQB3rEYIocgR/Ynwx5JNJEFMypng95od2/MOjr8iEda8+XfV7U/x1N383hxCKMqsXr16yZIloY4iYowfP/6tt94KRM3Rnwhv7nFDgGpuM5XQQZDey1x8SIaJECHkSV1dXc+ePZ988slQBxIBtm/fvmPHjgBVHv2JsKTpfJOpeViK/7ePz5C52INC1Cvf8OdW2dVT/N4cQij6xMfHDxo0KNRRRICLFy8GLhFG/9ssGV8aI1IEouYMGVzUty0U9hxkPfcXa7cFokWEEEJ+F/2JMEESnyZPCUTNmXIXmzGREhlPnW7FBbgRQihCRH8iPNN4dtWp9YGoOdPVo1EAEPXOtxTjEjMIIRQZov8dYV58r7z4XoGoOVYIBAHNVlAKriiXjrqJpe2BaBEhhJDfRX+PsEpf88GhzwNUeYarreqpGBUvTh2gFhFCCPlX9CfCeIlqdu60AFWeKW+7BwVCCKHIEv2JEFi2TFsRoLozZHCx3VRCZ7sBahQhhJAfRX8ipFn6eH1xgCp3LC7jolFtU/WSewPUKEIIIT+K/kQoJITz8m4JUOWZMihtN5UQAChFLNC0rbosQO0ihFCoFBQUvPLKK61LlixZUlBQ4DjV/uIJEyZMmDBh4sSJDz744NmzZ4MXqNeiPxHuf7H4kZ+eZljG86Wd53IqoYOw50DLGdywHiEUYZ544gmP1xw9etRqtTqObTbb0aNH3VxcWFhYWFi4evXqUaNGvf322/6J0q+iPxFSAnLp6OdJIiBfqZvBMsIeAyxn3f1wIIRQGDp82PNf8H379j10qGW29JEjR/r06ePxFrlcPm3atNLS0i6GFwgcSIQisrC4yGAzBqJylRDsDGisLk6Jeg60nP0LmID0RBFCKBCee+45ALjvvvsKCgq2bt06Y8aMgoKCoqKihQsXTp8+fe3atY7Lrrrqql27djmOd+/ePXr0aI81azSa77//Pj09PXDB+yz6J9RTQjJJoOaRgfpKHeNl+scRbcpJmZJSqKyXzgm69QhQ0wih6LNgB+3yb+tAWDGOUvCvKHnppZcKCgqWLVtWUFBw4sSJN954Y+HChbW1tcuWLTty5MgzzzwzY8YMABg+fPiyZcvsdjtJkgcOHFi4cKGbVpwvDjMzM//1r38F7KvxHScSYTdRGgltE5W/ZMjAZSIEgNjbHuOpkgPULkIoKs3uTlqYIE2+ElHuzt5+++1KpRIAJk+eTBDEoEGDnO8FJRJJjx49jh49KhQKMzMzpVKpm3q2bNniv5ADgguJkNpWsvPq9OHpitRA1J8pJ9rvSuggSA/I0m4IoSg2sRsBAfvDvVMcWRAAJBJJ+7OOp6Nisdib56JhLvoTYcqYuFtjJwvb9P/9p6OphAghFKHsds+rJY8cOfKLL74QiUQzZ84MQkgBFf2JUNFd+t2p9Xm2nv0TPY9r8kGmHPbVBaJihBAKgWHDht1+++0eL1MoFBkZGTabLTY2tnX5hAkTnMeFhYX+jy8Aoj8RAsDE7tdK+C669n6RKSNKdR0ODdXv/pm1GOXXRvxfTAghjli8eHHrj63f8DmOnSVLly7t6JTL28NW9E+fMFwy15xurDUEqtfm/tEoT6U2nz4YoKYRQgh1XfQnQoJH1DONeqshQPUnisFkB53N9Vlh977WsjOsLVijoRFCCHVS9CdCiVo4alB+L1VO4JpIlxFlHXQKCaGYn5JlLT0ZuNYRQgh1RfQnQgDYdH7b2uKfAld/ptz10tsOoh4DLCW41hpCCIWp6B8sY9XaBzfnJ+QrA9dEZss+9a6n/gh7DND8skIRuOYRQgh1QfT3CC3NtgtFVUUXdweuCffjZQSZefJx0wPXOkIIBUf0bcDkEP2JkBKSYCXSY9IC10SmHDpaXAYACL5APOCqwLWOEEJ+5HIbJmdhlG3A5MCJREjYiDhRAB+N4uIyCKGo4XIbJmdhlG3A5MCJRGgz2def2Ri4JtzsSogQQhHEuQ3Tpk2bZs6cOX369PXr1zsLIeo2YHKI/sEylJBkbXBXv7mBa0ItBr0NDHaQdvztrPvgSdUdT5MSeeDCQAhFAc3PX7BWc+sSUd4wUe/BjmPzyf1t1uggJXLFDfMcx4xRr930VZsKpaNv4qtbkpBhz0ZbTZnzVMykOwmBqPXFzm2Ypk6d+vbbb/P5/Hfeeee1115z7s0UZRswOUR/IiRIgpIQb+794PFRDwSqCYBuUqJMz+YqO1wznuAJzMWHJIPGBigGhFB04MUns1ZL6xJSevkPaFIi58WntD5LCMWXjymqzVkAIFulOlIRx6NbLahNdPhQsH///p999llBQcGSJUtal0fZBkwO0Z8IAWDIC73ybN0C2oRjvExuxy8iJYPGGg8UYSJECLknHXGDm7OCzFxBZm5HZwmhWHb1FDe3i/uN9DKMF1988cCBA5s3b964ceNrr73W+lQ0bcDkEP3vCAGAIOB4/emANpEp8/CaUDxgtPX8cVrXFNAwEEKo6+x2+7x585KTk+fNm1dSUuIsdByMHDnyjz/+2Lt378iR3qbVMMeJHiHLwkVN+ajUoYFrIkPuYeAoIRCJ+g43Hd7p/u81hBAKLcc2TLNnz3744YcpinK8BWy9N1M0bcDkwIlEWPp99eRREwPaRIYMfirzcI1kyLXajcsxESKEwplzG6abb765faFD1GzA5MCJR6M5M1OfPv1/JrvZ86W++t8qa+6IegxU3HRH4GJACCHkA070CAHgv9ct9nxRF2TKwWMiBJIU9coPaBgIIYQ6ixM9QgBYc/rHJrMmcPUnSwiNDUx2z1cihBAKK5xIhOW/1XWvyBHxhIFrggBIkxJlBq/Wl8F9ehFCKHxwIhEydlZmlZEdTx31i+5yOK/1fJlhX2Hz9+8FNBKEEELe40QipITkmZrzFbrKgLbSW0mc1njuEYr7DDcd29tm5QiEEEKhwolEyBOSufKe2crMgLaSqyRONXtOhKRMKcjoZTq+N6DBIIRQ4Jw7d+6f//zn1KlTb7311rfeestgMABAQUHBihUrWl/m3KrQZXn44EQipITk+dqLB6qOBLQVLxMhAEiGXGs8sDWgwSCEkG9c7kfYWm1t7ZNPPjlx4sSVK1e+++67Go3mnXfecZxas2bNhQsX2t/SUXmY4EQiJIVksiBpQKLnfbO6IldJnGryKhGK+4+2XiymtbjcGkIo7Ljcj7C1FStWzJo165prrpFIJElJSY888khFRYVjt97Zs2e//vrrNE23uaWj8jDBiUQoUYuI7nSVoSagrSSIgCCgzotZ+wRfIB44BjuFCKH2Nl/YDgDH6k5VG2qNNtOeiv0AsLN8r4W2XtJVnaw/48dr2nNuPVhQULB169YZM2YUFBQUFRUtXLhw+vTpa9euBYATJ060Xm47Li7u/fffFwgEADBr1iyGYdasWdOm2o7KwwQnEqE4QcD0tWgt+kA31Nvrp6PKm++Rj5se6HgQQhFHY9ECgNFmtNI2hmW0Vh0AaC1almWstNVkN/nxmvZeeuklAFi2bBkAnDhx4o033gCA2traZcuWPfvss59//jkA1NTUqFQql7fzeLxFixZ98803ZWVl3pSHCU4kQgDon9inb0LvQLfi/WtCQigGkivffISQ927tfTMADE8ZnK5IlQmkE7tfCwCTciaIeKIsZcbgpAF+vMa922+/PSsrCwAmT55MEMSgQYMczz8TExMbGhpaX7l169a6ujrHcU5OzvTp09988802D0I7Kg8HnPhdzNLsjt//WHlybaAb8j4RIoRQmFMqW3ZYlUgkrctzc3N37tzp/NjU1PTqq6/yeJcX7Jw7d65er//hhx/aVNhRechxIxEybJau+215MwLdkPfjZVqwbONXS+nm+oBFhBBCnebcetClBQsWrF69urCw0GAwVFRULFmyZMyYMa23ZBIIBI8//vgXX3zR5saOykOOE4mQ5JP0cNPmC0WBbihXCaeaO3MDQfASUpvXfRCogBBCqJNabz3oUlJS0uLFizdt2jRnzpxFixalpqY+9thjba7Jy8ubNGlS+3s7Kg8tgmUj71FeVlbWtm3bHA+v26uurlar1QRBtC5stmjqjY05sa5v8RcWIOZL26Xb+HK+17fQ9prXHoiZdKe4X2Tv9WyxWAwGQ1xcXKgD4RyNRsPn89s8vEJBUFNTk5CQQHbhZf/7779/8uTJ999/349RRasNGzYsX758w4YNVqtVp9N1NFrHN5zoEQIAXQExvJhAt0IA9Ighir1YaO3yLRQvduZDzes+ZC2uB3EhhBAKKK4kwrPfVW48/FsQGvJhvIwwu5+o16DmDR8HKCSEEEJucCURCsWCW7pPDkJDnR4vAwAAymn32+sqGIMXu1cghBDyK64kQpbPfnZgZRAa6vR4GQAAIITihL+/TkoVAYgIIYSQO1xJhAIx/9buNwehIZxKiBBCkYUriZAnJEuqS4PQUI6CKDOwli6snGBvDOyaqAgh5LMo24DJgSuJkBKSWr2WhYD31fgkZMiIczofG2Jt1rp3/2kpCeyOUQgh1BGX2zA5CqNvAyYHriTCzJuSbpw0ngDC86Vd5tt4GQeCL4i77bHGb95g9Br/RoUQQt5wuQ2TozD6NmBy4Hm+JCrwpNQ/i154etSjSmHAZxP6Nl7GSdhjoHjg1dpNXytvedB/QSGEIkPjCR1jv+IvaWmyUJwoBACr1k6baeex9oKxzb2qvnKCIgBAe8EoTxc7j63aK5ZME8bw5JmuV2BwbsM0bdq0zz//3G63z58/35EF77vvPqvVOnfuXOfFjg2YHMezZs3atWvXmjVrZs+e3brCjsrDCld6hADw+vgXgpAFwR/jZRQFs42Hd9CaBs+XIoSiS8Nxbf3h5tb/jNUWxylLs631cZvL6g83M7aW3zyac4bWx20u07TLoE7ObZg++uijpUuXvvPOO3v37nUWRt8GTA5c6RE2l+h//+vg0Il9EiTxgW4rV0m8dYzpSg2kVCEZcq1++7qYKff6KyqEUEToMSu1o1PydDGki53Hve9I7+jKbtcluDz2Xv/+/T/77LOCgoIlS5Y4Cx0bMCUnJztLtm7d2r9/f8exc6Olt956q3VVHZWHD670COXpkqwRyRJ+MNZj7K0kzmhYpmvjcuTX3MJTd/Pq0ghcLRYhFOZefPHFKVOm7N69+6mnnnIWRt8GTA5cSYSUkFTHJVAEFYS2pDxQiYgyfZfyExWjko64weNlljOH6z9+risNIYRQG3a7fd68ecnJyfPmzSspKXEWRt8GTA5cSYQAsLl0+wXNxeC01cXxMl5i9JrGlW/Kxwd8n0WEEHc4tmGaNWvWww8/vGjRooULFzoLo28DJgeubMNkbrRW7mjoPi3Z5S1+9+gfdDcp8Vg/P/ydwVothEDo6gRb//Fzgm45ihsXsFYLrannJXT4aiEIcBumUMFtmEIFt2EKJtyGyQ9Ymi3/q3pPxf7gNOevhdYYg7Z68V2M2cUQL92O9YzZqLhhHgBYS081fvVa15tDCCEO4koipISUiBUNSx4UnOb8lQhJqULYY4Bh909tyq3lJbrfVsfNfwJICgCEOf3pplp7fVXXW0QIIa7hTiIk7WamQlcZnObyYv229La8YLZ+xwbWam5dSPD4cXMX8eLULZ9JUtR/lOnobr+0iBBCnMKZRCggwQ4aiy44zamEQBJQ64895/nqdEF238pn51T++xbDvs0thcmZotwhrS+TDLzadGSXH9pDCCGO4cqEeiCA5BP9lLlBazBPSRxrYq8V+2F107h5T7BWCwC4HjUDAADC7H60ps7eUMVTBWlAEEIIRQeu9AgBgMm2fnP8+6A1NzaZ2HqpS+vLOBE8PimRkRIZweN3eBFJigdebb1wyi8tIoQQd3CmRwgw+p6Bo2Fg0Jqb2I18YA/9ytCgNQjKafcDEYztNRBCKJpwqEdYoav8+ezmoDU3LIGoMLCXDEGcpolZECGEOo9DPUKpXdYrJjtozVEEXJ9K/lrB3tML8xNCyLXa2to///wz1FFEgLNnzwaucg4lwub9RmF3EfiyDruPJnYj1pey9/QKXossbTef2CfuPzp4TSKEfDVp0qQ1a9Y88MADoQ4kMowbNy5ANXMoEcrG8Nac/uUBuCtoLd6QRj70u83KUIJgPYEmSKp5/TKeuhtf3eH+LAihMJGRkbF9+/ZQR4G49I4wQRL/QH7wsiAAxIugt5LYXR3U14TiAVfpCr8Bhg5eowghFMk4lAj1euOzW5Z4vs6vJnYjfy33zyQKL8XcuIAxG+s/e5m1WYPZLkIIRSgOJcKGPbo7bAuC3OiN3YhfyoO6vwchEKrufp4US+o/epox6VufYm1Ww++/GA/vCGY8CCEU5jiUCHki6lJDJc0G9ZlhvoposLCluuDmQooXN/efgoxetvKWcVaMQastXFn98gLTX3s0Gz5mLf5Y/A0hhKIChxIhJaQsZluQt18kCbghjfy1IuibPhJEzM33CHu2LCCgK1pLN9cl/P31+PsXC3sM0O/9NdjxIIRQuOLQqFFKSHYTpvFIKsjtTuxGfHOW/VvwVjl1IWbSnc5j5fQHCKEohMEghFBY4VSPkDxVfabGUBfkdq9PJXdWM+awGcVJSmQExaE/gBBCyD1uJcIcaXe1NIgz6gEAIFYI/eOIHVVBfzqKEELICxxKhNJUUdnA8+XaS8FvemI38teKoE6i8IgxaPU71nu8jKXtQQgGIYRCiEOJkCeieuVlqcRxwW96YlqwJ1F4RAjF+h0bLOdPuLmGpe3Vi+9i9M1BiwohhIKPQ4kQAFTiODsbgi7OABVhtMNZbRjlQoLHV9y0QLPhY+h4HC1B8US9h+j3bAxmYAghFGQcSoQsw+5fc6JCWxX8pgmACanElkthlAgBQJI/nmVo45Gd7U9ZS09ZS08DgGzsVMOejfiAFCEUxTiUCAmCGD5iQF58z5C0PjY5/MbLEETsrX/XrPvIdGxv62LWbmtc+SatawIAvjqdn5JlOrQ9NBEihFDgBSMR6nS6Z555Ztq0ac8++6xOp3NfvmvXrnvuuWfq1KmPPvpoRUWFP+MgYDexp/D8Nn/W6bXxKURRFRNmmRAEGb3j73tZt3UVa7c5C3W/reKr08X9Rjo+ysZO0+3YEKIAEUIo4IKRCFetWqVWq1etWpWYmLh69Wo35VVVVa+//vqiRYtWrVo1cuTI119/3b+RFGSNn9D9Gv/W6aVuUkLGI043h1sqBH5aTuI//kPw+I6P9toK/a4flTMub5Am6j0YaLutuixEASKEUGAFIxHu3r17ypQpAoFgypQpu3btclNeVVV1zTXX9O7dWygUXn/99eXl5f6N5Oxv5ccvFvu3Tu+NSya2h9vT0TZYtmn1O4rrb6OU8ZcLCSLx8Xf5SbjBIUIoOgVjhZGGhga1Wg0AarW6sbHRTXl+fn5+fj4A0DT95ZdfdrQfsdFoLCgoEAgEzhKRSLR582bHcWNjI0VRBEG0v7H5iIGVm+ul9f760jolX8bfXMq/NcEYkta9QZ8+QBv0RO4oc32nv0VWq9VgMDBMeE2X5AKtVsvn843G8P25ilaNjY0EQZAkh0ZahAOr1arX61mvl41WKpU8nodMF4xEyLKsIy2xLNv6F2VH5QcOHPj000+HDBly5513tq8NAEQi0X//+9+UlBRnCUmSMTExjmOTyRQTE+MyESrk2uTYjJgYiT++rE67MRteOgWKmBgXkYUHNn8Mk9OHio314V6LxUJRlPN/AQUTn8+XSELzU81lZrM5JiYGE2GQWa3W1r/wPaIoz+tLByMRqlSq2tratLS0+vr6+Ph4N+Usy37yySenTp165pln0tLSOqqQJMm8vLysrCyXZ/l8Pp/Pd5kI9YShsOSvublTu/w1+SIrBmQ8+zkDlasM11TI54NE2tFJw77NkoFjCKHY5VmGYRzf+YAFh1zj/0+oA+Ecx7cdE2GQsSzr9x/4YPwXjhgxorCwkGXZwsLCUaNGAcDRo0ddlv/111979+59+eWXVSqVyWQymfy8bV6cIrYgdZx/6+yUCHhN2DFL8UEcPooQij7BSITz588/f/78nDlzSktL586dCwCLFi1yWX706NGKiopp06bd/D/+jcRKWfZfPOzfOjslHGcTek1eMMd0ZGfN6w8aD27r6hR7hjb++Zuf4kIIoS4hvH/lGD6ysrK2bdvW0aPR6upqtVrt8tHo+c2VRp6x7zU5AQ6wQ+UGdsgGe/Vcfrg+G/WEZc3Fh3Tb1tjrKpXT7hP3H+08Y7FYDAZDXJxXS7ka9v6q/XVF0vNf4YZQXafRaPAdYUjU1NQkJCTgo9Egs1qtOp1OpVL5sU5u/RpKv05dqQ/BEmtOjtmEp5rZvLB9TegeQYh6Dxb1HmyrOOtzHazVrN30NSGW28pLBJkh3bAYIYQ4tcQaABhsho1nt4Q2hnHJxPbKyOuFt8FPy+GnXe5Ya7d8a6/xdtKnrmitMGdA0pPLMAsihMIBtxJhjFDxt3zXUzKCZmwysaM64hPhFRiGAELzybPWHz5ys5eFA61r0u/8QXHTAnD17BohhIKPW4mwqVj38XurQhvD+BRie/gtOtolJCkvmB33r48ZbUPzhmXuryVIKnbWI7w4dXBCQwghj7iVCGN7ye964JbQxuB8TRjaMPyO4AuEMx+1nDnifuN7UqpoPcTG8PsvwNCBjw4hhDrErUQIANvLdltpa2hjiI7XhO0RQkn8fS/rf/+VMWi9vMV4YJvpxL6ARoUQQu5xLhFaaRvDhng9zCh8Tfg/lDIh6V8fklJF+1P2xhrWam5TKB050fD7r0EJDSGEXONWIjQ3WpPXZ4p4otCGEYWvCVsjW1b2Y2k7Y9Q7/zV+tbTNDsAAIB44xlpWTDfWBj1KhBBqwa15hBSfbG7QnawvzovvFcIwIn42oXcsZw43frXU+ZGnTpfkj2tzDcEXSAaPN+zbpJh4e1CDQwih/+FYIhSSQkYY2izoMCGN2FDK5g2M5kQoyh2a8sr3Hi+Tjr6p/sN/KybMdXYlEUIomLj1aJQUkAzNHKw8GupA4K5e5KfFTPQ+Hu0EvjpdOrSAMepDHQgKJxG49COKXNxKhABACch0cYcbPAXNkHgiVgi/RePYUR8oblpAynzcyJBuqtX8/AVrC/FIYORf5lMHQh0C4hDuJUIpadaHxS/Ne3uRn5zG/dyvYKs4W/XC/MYVrxoPbvPmesP+LTVvPmy9cLL+o6cZE/YpowTdWGs8WBTqKBCHcC4R8q9iTmhOhToKAIB5OeTWSvZ2060AACAASURBVKbKGOo4wgk/LSfhwVdFvQdrN35pPrnf/cXmk3/qd2xIePDVhL+/xu/Wo/6Df+PztOhgrSixnDmM/5soaLg1WAYABo3NA8gLdRQAADI+zMgkV5Qw/xrAuT9H3OAlpDr+NXzxf4mPv0vFdLjZiih3iLDXIMdGTsqpC201Zbh+aXSwlpfQuiZb5Xl+anaoY0GcwLlfwWXaSy/teSPUUbS4tzf58WkcMuOCICtPOmZy07dvtT/FmA0tRwTRejtDvjo9OLGhQLOVl/DiU8zFodxDG3EK53qECeb4R9MeCHUULYYlEDECKKpir03Brkxbiutm2/qVXVHEss1rP2BMhrj5T7i50V53CSgerusduRQT51PyOErpz51XEXKDcz1Cu5XeVRZGi1veg0NmOkIQ/KQM5yeWtjeueNVWUx478yH395lPH2z8cglL2wMcX9ewrPHwDt9eg9HaJtZq8XtE4UOQ0ZuKS8R5pShoOJcI5WkSSKFZCJfHkXNzyM2XmFpTqOMIb6zF1PDxcyzDxN/3MiEUu79YdtVkSq7U/rIiOLH5hjEbDLt/rnvvCXtDdWfv1W9faynBx4YI+Q3nEiEA3ND9mvAZjxYjgKkZ5Jcl2CnskK3ibPXiu6n4ZNWCpwge3/MNBBE75zHjwSJz8aHAR+cjUixL+Ptror4jat9+xPDHJu9vZAxa/Z6NppN/Bi628MHoNaEOAXEC5xIhS7OfrVxVYwijVZ7v7U0uO40jZjrES8pQ3DAv9taHgPT2x5WUKuLmPdG08k1a1+SfIFjWVl1m/HNr15+42usutWzBSBDy8TMS/v66Yc/G+o+f83ZtHYoXM3G++YSHuSWRq+nbt6xlxQBgqzhb9567l8EI+QvnEiEQkHekf5IkMdRxXDYykZDy4FN8U9gBgseXjrqxs3cJc/pJR9yg/fWrLrau3/1T/cfPVT59a8Onz+u2r2v67m33L/bsjTWWM4ctZw5bzhxpv+cwa7PWffCUteKss4SflJ7wj7d5CSm2yvPexEOKJLJx0wmKZ6sq7fQXEwlMJ/ZTChUA8FOzaV0TrWkIdUQo+nFu1ChBEozQ/lfZ6QGZuaGO5bJPx1D37KK/v8C8N4rqEYMjSP1DMeE259JrrNVC6xoBAGjaWl5iLT1lLTuT8NDrHp+1EnyhdMQNsbMfpRSxrM3avGEZYzGRIklH11tLTxn+KAQARtfEi0+Ou/0pgi9wntXv/EGQ3kuQfsWy7wTFU067v1NfmqjPMPOJffzkzE7d1UWMQWstPSnqMyJwTdDNdQRBUMp4AACCEPUaZC4+JB1WELgWEQIOJkIAEMUI04jkUEdxhaEJxMGpvPdPMiN/tM/NIV8ZSkm5+D/jbyTlHFljvXiq6bv/AgCQJD85Q9C9r3LweOJ/4xKNh3cQQIgHXe34yBi0zr2FpcOvd9ZH8AWxt7oYs2rYt1ncd4TjFkn+OMduUyxtb/r2rfqPnlbd8zwpljmq1RV9n/iIi8mR3mCtZtZmdbQiu2oya7f5Vo/PdNvX0U21AU2E1vKz/G45zo/CXoMtpw9iIkSBxsVft3wZ1dSgUWX4uMpzgPBIeKQveUsW8dg+ZsA6+7rrqP5x2DX0G2GPgUnPftHRWZ4qufGbN0zH9sRMWagrWms+9WfSv5Z59UqSZTUbl5uP7xX1HtzmDEHx4ub+U7t5JWsxgVgGANrN30oGjeUlpLqvsKP1cfS7frLVlMXd9jgA8BI7v3A8y9qqL/rciWSMesPvvwBBAMN4/7K2s2wVJYK0y4lQ1Ctf89Nnbr4nCPkF994RApiEptq6MH3xkColVl1DzepOrMBxpEEkSO+pXvQeKY+revF2RtOQ+MhbHn/X63est5afafruP5azfyU8/KbrpeAIQjFhLqVMAAB7Q5XxwFbFhLlu6rSWn6n78N8uT7E2q37HOvk1t3j7JbWj+fmL5vUfAYBuy3emwzs7e7t+5wZx35GUIs4xkiVArOUl/G49nB8pZTwli2n9ShWhQOBijzBZreaLwnqu7o3dyEf2th1ngQKK4AuU0+6TjZ3q5ZI0VKy67j+PCXsOSnhgCSEQebyetVqUU+9zv9uUIK0Ho282Hdsr7jeyzSnD778IMvNarzDQKYY9G03Hfk/8x9sAwEtM0+/60fkc2EuSweMJvsBy4STBF/oWgzfE/UcLs65YCjj+gVcpeWzgWkQIuNkj1A9r+l66NtRRuDMsgSjRsM1hsVsUt3i/MJu4/yjVvS+q7nnemywIAPzkTMnQaz1cRBAxN9+j+fmLNsNNWbtNV/S94vrbWhcyZmPN6w8C4/nJgfnkfu3mlfH3vUxK5AAg6jvCXltur63wJmwnXkIqpUyQDBrLT+3eqRs7RTriBlKmbF1CKeLwuSgKNC4mwr4JvR8Zcl+oo3CHT8KIRGJXNT4dDWui3oNbr/rtrzqpGJVj3KmTfsd6fkp3ftoVWzGQIgmwjMcHldayM40r31Ld/TxP1TJAjKB4kmHXd2oWP0ewNivug8hNXEyEJrv5p7OFnq8LqXEp5PYqnGTPRcqb79EWfkNrLy8FwNrtMTctaH+lKG+Y+ZSHJWb029fG3faYIL1n60LpiBsM+3/zctyprao0xAu3sixrCewihIxBq930dfVLC5pWvokzFzmIi4nQrmFiC8N9a4JxyURRJSZCLuKnZYsHXm27dHmEiGLCbS535hPlDTV5WmIm7vanRHnD2hTy4pP5KVmmY797DIa12+o/etpefdFZYqu+qP3lS483+kC35Tt73SUX5dvXaQLT4uUmtq6mtY0JD78h6jvScuZIQNtCYYiLiVCukgy5r3f4rLvt0tB44ryObYjmPQZQh5TT7hPlDvV4mTAzl26qZX1aRi525kOi3CEeLzPsK+Sn9Widhil5rH7XT4HoI+p3/eByfQNR78Gmo3ucayN4xjC2S+c71bGLufme2JkP8xJShT0HWM7+5f2NKDpwMRECwEt73jDawnrHBx4JI/E1IXKPpES9BtlL2vZgdL+t0m35zv2tvPgUUiR1fw1L23VbVyuun31Fm1IFT93Neu64D/G6QWsaWIahYl2sfchPzhSk99Tv+tGbeiznT1Q+PbNhxavOJes0P3xiu+TV8nUAIB16nfKWB728GEUNjibCV8Y+I+V3uEpWmBiXjK8JkQfygjlUq8UCbVWljSteNR7eIRk+oatVM7T25y/4id0EGb3bnBHlDjWf7MSq34xB63H1c1tFiaDVDMI2Yibfpdv2PWPUua/EXlvRuPz/VHc+nfTUx84uNUvbzacPurxe++tX5hNX7E5KCEStl8RDHMHRRLjp/T3FJy+EOgoPxqfga0LkAT85k4xLAgBLydH6j5+t/+hpfkpW4sNvUgqv5t7R2qaOHnI2fLXUVn0xds5j7U+J+wwzeZcI7fVVzd+/V734bkvJUfdXWsvP8lutKdMGLyFVMvAq3eZv3dTA6JvrP342ZtJdwp6DWpcLewywnHXduvHILtcrISCO4eKEegBIFicpzPJQR+HB4Hii3MDWmyHeq4lqiLtYg6b5h49lY25W3fWcV1s2/k/j168Js3IlQ65tv/Cbctr9lDzW5Rw+fmo2azHZ6yt58SkuqzUXH7JVnLWWlVjOHZONvjHp3584Zwday0t4cWrnUq5O1vKS1su6tqe4YV7jyrfcLLem+fkLydDrJO0WJhVm92/65g2WtreZ60JrGxl9s8tRSIxR55hziTiCoz1CQspom4yhjsIDioBRicROfE2IPCGkMepF70uHT+hUFgSAmBtvt9dV1r3/ZOUzsxs+e1G37XvnmBR3M9kJImbSnQCXz1rLSzQblzs/slYLY9SLeg5Mfm65YuLtrefIW4oP1b7zON3UdkNQniqpzaYcbZAyZfzCl9xMrlfOeNDlCnakRMZLSLVebDvh0lJyVJjdt32FdHNdzasL3W+2Fc6spadaz71B3uBoj1DH11uaImDhlnEpZFElOz0z1HGgKCXIzI3LzAUAurnecuGE9cJJWtfkzfI6kqHXOY8tJUcavnw1dvY/nCXifiPbrxLnIL9uFiEU176zKG7Oo4RYRpCko0+mnP63Ln4tbt7tCXsMsJQcEXbv07rQUnJU2GNg+4spZQLBF9lqyjq3oB3L2msreOpunbglAMyn/mz4YrFk6LUut0nxiDHpiVZ7tnCHVz3CW2+9ddWqVYEOJZhyUjOVtNLzdaE2LpnA8TIoCChlvGTQWOX0v3m/yJyD6eiuxhVLVXc9I+7r7fZMsjE3x0y+S/PT582r33GsA+4blrYb92/xZu9lSf44fkrbleE6SoTQkjg9vNR0BOA8tl06X730fmt5ice7usL9GgjGA9uavn1bddezrNnkQ4/WeGh79Ut31L33BKNv7kKMEcmrRJifn3/kyBE2Yp8VtHfWev7CpfJQR+HZIBVxycjWhPVED8Rdhj0bm9cvi//bK8LufTt1oyR/XOLj7yY+/m7C31/vbKNNq/5rPLxDt3VN9UsLjIe2C3P6e7yFn5bTtofKMLLx0/kddOAcPUj3ddqqL9KfPt2qiWzF9XOMB7Z6/gI6iTEbGbMBAOim2qoX5ms3fulyCK5++zrNL8sTHlwq6j04bv4TPizQKuzeV/3kMlHfEbX/fdzeUO2H0FthaXsnZoIGnVeJcObMmTab7aWXXvrjjz8uXLhQ1kqg4wuQIf369x/l7oVEmKAIuEpN4mtCFIbMxYd029clPPQGPyUrmO2K+w5v+vp1W3Vp/H3/F3//YmGPAb7UQpKyqyZ3lC2EPQZYzh1306miNQ31Hz9LjpnWulAy5FrToR1tFkxvw1p6urN9NeO+Qs0PnwIAFZuY+OjbjElfs2Rh/Yf/1m762nz64OXaCDLx4be8fDZLN9ebDu9sXv9R/Yf/dgZMKeOpGJViwlz5uOl17y6yVZV2Kk73TIe2N658w48V+pdX7wjvv/9+x8Hu3bvbnNqyZYufIwoKnVB3KOHQjXCd50tDzfF09Nag/qpByDN+UkbiI2+22SwiCER9RiQ9v4JSxAWuCUoRR8qUtkvnXM7oYC2m+k+ek42eZMy74mkwLz6Zik8xnz7Yfk27pm/flo6aKOjWs3nDMn5yZuytD3m/ubHp2F7nPpQ8VbLylgcVNy2wnj9hKT1l2LPRuSO0bOzUdoGyAHBFsmdZbeE3hn2bWZtFmJUnyMwTDxjTvkXp6JtImUK/+yffXjS6pNuxXjZmir9q8zuvEqEz21mt1sbGxtjYWKEwgHuSBYGIEiZJXaxhEYbGpxCfFmGPEIWdEM7A8yEL0poGfdHamKkLvbw+fuFLvNgEFycYumH5YmFGrvzamcaamjYnpUOvNf65tU0ipLWNpmO/K6ffDySZ8MCShs9fblj+f3Hzn/Rm5j5j0NounW/zLpMUy0R9hov6DHd/b+PKN8R9R7ROdbSmwVp+NuFvr/AS09zfKx4wxmWO9I3l3DHWZpO2m9kSPrz9q2THjh0LFy686aab5s+fP2nSpHvvvXfnzk5vch0+pAJJYmMSbY2ABDMgjqg1sZXG6HlBi1DwkRK5fu+vjNkIAPa6S83fv+f+ep4qCUgX23drfv0KSEo54wGXd4kHXk21S5/GfZvFA8c4hmISApHq3hcJvrD+w6cav3ndOSTHeuGk4fdf2ldoOrFP2HOQb4vdSIcVaH5e3npED6WMj7/3BY9Z0O/0O9bLr55yuW/qxSaaQeZVIiwqKlq8ePHo0aOXL1/+888/f/nll6NHj3755Zd37NgR6PgChGGZjft+Y20RkF1IAsYk4VprCHUJwRcIMnpZzx8HAPOZwz4P3JCPnapa8FRHDzZJiSzm5nuuKGJZwx+bpCMnXo6E4sXNe0LUd6Qwu58zJ5GyGO2vX7WPynxsb0cTUTwS9hjIS0gx/P5LV+ZEMgatl4NIGX2zvcbFCER7Q7Xl/InL820YpvY//7CWnvY5pEDwKhGuWrVq2rRpCxYsSE1NFQqFKSkpd9xxx9SpUyN3TgVFUPfdeRtP6uIvvjA0PYv45mzY/Q2FUGQR9hjg2GLJcuaoMMerITbt158jZUpC0ImlnszFh0iJvO0yqgQhv+YW6YgbnI+XeQmp/PRebbYFZmm75fzx9m8cvRcz+W7dlm9r337E5f5W3tAVrdVtXePxMtNfv9e89reG5YvbJ11b2RnZmJsJwf/eppGkYuL8hs9fstdX+RZSIHiVCC9dupSXl9emsE+fPuXlETADoSP/+XNZrbE+1FF45ZZMcl8tW6bHTiFCvhP1GGguOQosazl7VNjT9QzC1rS/fuXIAeYTf+h3/uBbo4a9V3QH3ZCPnarfsb51IiEoXvLzX5ESmW9NAwA/OVOUO0w84Kr2S+h5STryBsOfW93MX2RM+sZv3tD89JnqrudUdz/ffiCueNDVbVb8EeUOlU+4rWH5/7kfYRtMXiXC1NTUkydPtik8depUWlqwnzX70Zzk6RKNh21owoSYB7OzyeUlmAgR8p0gvSfdUG05e5SUKrwZ6SPI6G0+ub/p27eb1y9zsyB4e6bjfxj2bHQcx0y+UzJ4vDd3OXJzm4n8lztSvlLOfEh+7Uyfb+epkgWp3U1/7XF51nrhRM1rD5BCsfqfHwgyc3nxyV5WKxs9iZQodDs2+ByYf3mVCGfNmrVu3boVK1ZUVVVZrdaqqqoVK1asW7du1qxZgY4vcKpONF7c7edJo4GzsDf56WmGxlSIkM9ISn79HNPxP7yceijM7msrLwGKUv/zgzbLs7lHyZW6Hesdx7z4FO9XLJONm+a80V/aLDXuA+nIiYa9m1xXLpTEzv6H8pYHfUjYsTMf0v22im5su+qsk6XkaNBWfPXqezR+/HiSJL/++uuvvmpZzSgjI+Ppp58eN25cAEMLMA3ZLNNGwCprDv3jCLUYfrvETkjr9IIRCCEH+TW3mE8dIMVePQoihOLER//Tqb6gg2MHR2tZsftlxNuT5I+nYuIdx7SmgaCo4E/TbE/Ub2Tz2g/sdZfaP1/lp2Txoe0cZ3tDdfPa91V3P289d4zWNXfUIebFp7iZT8kYtM0/fAJ2m2z8DMmQa7qezt3ztvaxY8eOHTvWYrE0NTVFwTxCABiU3be0uMM/RsLQPb3JT4uZCWmRMcAHofAkyh3i/cU+ZEEHyZBr9Tt/iJ31j07NfCD4AucEed2270mpQnH9HN8C8COC4klHTbSWnfHyRSMvTk2QlPaXL61lZ6SjbnRzpXhg26mKjEFLSuRAEKRUoV70nqXkiG7b99pfvhTmDGD0zfF/e8X3L8Otzi26LRQKk5KSoiALAsDvTX82NUTS2rJzs8ltlUwtrjuKUNiTDLnGeLDI+OdvPtdgPu77xAm/U0y8vXXHrmnlm+7WYiWI2DmPGQ9ut9dVSgZc5X0rjF5T+/Y/LOePO0uEPQa2LKSX3bftvBS/4uii2wBQ0PdqgTmSMrqMD1MyyBU4jwKhsMeLU4t6DxHnj/XtdvPpg0CQ/ORMvwblH4b9W6zlJYLMtvMIWiOlirh5T8iunuJyUYK2GNpy5ghrs9Z/+rxk8Hhhdr825/nJmdJRN/JT2+4f4kccXXQbAKqs1TRD05ZIyiv39CI/Pc1E1d8jCEWp2DmPkiJfxqXbqkrrP3o6fLqDrdlrKzQ/fha34N8eH/kKc/rJx8/wpk7GbGz8+rW6D57iJXZT3DDPH2F2GkcX3QYACU+c8KiEEnq7yFw4GKUmeCTsrmbHJOGQGYTCms/LgvOTM4Xd+4r6jfJvPF1n+KNQV/R9zE0L+EnpXt3g3VZQpEQeM+Uew74tsbMe8WH3KL/o3KLb0UQpUtJsuEzn9N5dPcnPipkxSThkBqGopbhxgTAzN9RRtGWvKeMnZ3q5PkCnSAZfI+43KtBDQ93g6A71AKC1ar88Fnlf1IKe5A8XmSZLqONACAWMMKef9/s0BY10zM2xsx4JUOWdWrjO77g7WEYpjJlrn1N3SBPqQDpHJYQJaeSDv9N15lCHghDiEl6cmhT7vt5bOOPuYBkA+Mj6iaxfJA0cdfh0DNUzBnLX2F44RFsi7+EuQgiFF+4OlgGAx0c/IOJHXiKU8eGFfGpuNvn0AabvWvsrQ8lbs8LuKQpCCEUK3wfL/Pbbb0uXLvV3PEF1vqk0U5muFMaEOhBf9IghVl9L/XaJfXgvXa6Hx/phLkQIIV+4++1ZUFDw22+/tf4Y6c9C22iobi77LjJ2YurIdanEG8Opn8oiaTYkQgiFFU53I8ZkjTRf6HCfrUgxNpk4WM/qI/7rQAih0OB0Ilxb/qNFb2cjfKkWKQ8GxxM7qyP7q0AIoVDhdCKc02e6QMqz6SN+5GVBKrnlEj4dRQghX3A6EZ6sL7YmmjVn9aEOpKsKUoktl7BHiBBCvuB0IkyUJsTnKRpPRXwiHBxP1JrYCgPmQoQQ6jROJ0KFQKbIlSiyJKEOpKtIAsYlk1srMREihFCneZhHuHTp0taTBe++++4AxxNUdcaGwtqiu0bdFupA/MDxdHRBj1DHgRBCkcZdIozoVWO8kSpPvqt/NGRBALg+jXj2IM0ChfszIYRQp3D60aiNtj269RnaylT93hjqWLoqQ0YoBMRfjfh0FCGEOofTiZBP8V8d9xzJI/jSaNjeD8eOIoSQDzidCAHgYPURnV0fPyAilxttoyCV2FKBswkRQqhzuJ4ITXZL1OyzeE0KubeWNdlDHQdCCEUUrifCazPGSPgSYOHc95WMPbIzooIP/eKIPTWR/VUghFCQcT0R7q7Yt+b0D0CAodKsPW8IdThdVZBK4FprCCHUKVxPhFelDb8tbwYAxObJG0/qQh1OVxWkkjheBiGEOoXriRAAXtn7Hxtjj8uTN56I+EQ4PIG4oGNrTQAANgb21bJvH2c2Y2pECKGOebVDfXS7o99siqCkKTyWYU11FnGCMNQR+Y5Hwrhk8r7ddKOFPdTAdpcT2QpizXnm+lT8j0YIIdfw9yMwLFOlr06VJ8f2kjWd0kd0IgSAu3oRB+vZUWpqRCKh4APNQsZ39hNNbJ9YXHMGIYRcwEejUKGrbDJrACBxaKxAEfF/GUxOJ1/Ip65PJRR8AACKgDt7Ep8V4wgahBByLeJ/73fdiJQhjoMo2IbCpbt6ksN/sC8ZSgmjYf0chBDyM+wRQqOp6V9FL4U6igDKkhMDVMSGi9gpRAghFzARQpw4dun45xzHplqL/pI5tPEEwj29yE/x6ShCCLmCiRAAYOO5LeebLwKA3UQz1ihMGNMyyb8a2XNanEeBEEJtYSIEAMhT9UyUxAOAPCMaNqxvT0DC3GzyizNRmOMRQqiLMBECACTL1I3m5lBHEVgLe5Ofn2HsmAoRQuhKmAgBACr1NX9WHXIcN57UWZpsoY0nEHoriSw58Svu04QQQlfCRAgA0F2ZMaPXZMdx/VFNU7E+tPEEyD29yE+L8TUhQghdARNhi2d2Lqkz1gOALFVsuGQKdTgBMbs7+XsNU2nEXIgQQpdhImzx8tVPJkjiAUCaKorKGRQAIObBLVnkA3uYP+swFyKEUAtMhC3ONJ7bX3UIAGSpYmOVGaI0U7w0mBoST8wpovuttb99nKmNzq4vQgh1AibCFhKeOF6sAgBKRPJlPFOdJdQRBUSCCJ4ZRJbM5L03ijrawPZaY3vzGA6fQQhxGibCFt0UqQqBzHEc011qaY7CgaNOBMDYZGL5WGrrjbyPTmEiRAhxGibCFjRLv3vwU4ZlAaDHnFRlT1moIwqG/HiCYeF4U5Q+CEYIIS9gImxBEdSLY/5FEpzbtG9KBrG+FBMhQoi7MBFetq54487yvY5jluFKbpiWSa4vxaejCCHuwkR42Q3drxnTbYTj+MQnF+1mOrTxBMdoNVFlZC/ouJL4EUKoDUyEl9Esvav8D8dx3/syeSJO7GNLEjApnfzhIiZChBBHYSK8jADCRkfzYNGO4NNRhBCXYSK8TCaQjssYbWdanojSZq7khmtTiL8a2WqcXI8Q4iRMhFd4/+Dn55tLAcBUazn85tlQhxMkQgquTyM3lnEl8SOEUGuYCK/w8JB7e8ZlA4A4QWjT2+0mToyXAYBpGQQ+HUUIcRMmwitU6Co/OrwcAIAAabLIUBmdq2+3d1M6ubuG1XLxDSlCiOswEV4hURI/O2+a41iaKjJE6TYU7cn5MEpNbCrHTiFCiHMwEV5BQAnKNBVN5mYAkKaK9VG6MaFL0zLI9TiJAiHEPUFKhDqd7plnnpk2bdqzzz6r0+nclNM0feeddwYnKpfqjA1W2gYAsjQO9QgBYEoG+Ws5w41VBBBC6LIgJcJVq1ap1epVq1YlJiauXr26o/J169Y98sgjFRUVwYnKpWszr46XxAGANFmUc2sqADBWhgujZhLF0C+OKKrETiFCiFuClAh37949ZcoUgUAwZcqUXbt2dVTevXv3efPmBSekjpxrLn1r/4cAQFCEPEMMANpSY+2BZsdZU53FZojapDgtg7ytyJ69yt5/nX3IBvu1v9gf30djHxEhFN14wWmmoaFBrVYDgFqtbmxs7Kh84MCB3tSm1+tzc3OJVjtFiMXiU6dOOY7r6uoAgPB1HwkZiG/PvLWmpuZyUQxQMeAoaT5gatpnTLxBLs0W+FZ/OJsZD9eNJc0MGOyEnSU0NuLri8L8tdRH+fpecg/50Gq1Go1Gmw0HngabVqvl8/lisTjUgXBOXV0dwzAkiSMtgspms+n1ervd7uX1KpWKx/OQ6YKUCFmWdWQmlmUZhvFY7p5MJisqKsrMzHSWEATh/EVA03RCQoLPiRAAvju1fmjyoGxlZvtTCRNBl2s8u6rScobNvjWZJ4629UhTrvw4PRe+OsvO+CPm6QHkQ33cfU8tFovBYIiLiwtsfKgdgUDA5/MlEkmoA+EchmESEhIwEQaZ1WoVCoUqlcrL6735DwpSIlSpVLW1tWlpafX19fHx8R7LPZJKpTKZ671zSZIkSbIriXB8xlUqRd8DKgAAIABJREFUcWxH376Y7rKBj+Vc+KHqr7cv9JiTGpMt9bmhiLCgJ1ydTN5WRG+vhs+uplRC15eR/xPc6BB+50MGv/MhEYhve5D+C0eMGFFYWMiybGFh4ahRowDg6NGjLsvDgUIoL2k67+YCSkjmzEzNnpFcsbUOODC4JEtO7JjEy1HAwHX2TRUc+IIRQlwSpEQ4f/788+fPz5kzp7S0dO7cuQCwaNEil+XhQGfVl2rKPV4WmyvvszATuLGnvYCEN4ZT311D/f13+vbttB5fBSKEogXBspH3B35WVta2bduysrJcnq2urlar1V15NOqDc2srU8aoxIkdPDeMIlob/HMfveUS+8XV1Njky99kfEcYKhqNBt8RhkRNTQ2+Iww+q9Wq0+m8f0foDfwvdO3N/R8UN3Zi94mMG9VcyIIAoODDsquot0eQc4rsS4/ikmwIoYgXpMEyEefxYQ906vroGz7q3pQMcngiOWyDfUgCcW0KN54OI4SiFPYIXavUV393an1n76o/qtWWGgMRTxhKEsNX46g7d9ANllCHghBCXYCJ0DWlMGZU6rDO3kWb6Yrf6gIRT3gam0zM7E7cuwvXnkEIRTBMhK5J+GKaseus+k7dlTBYqS83mWo51EVaPIS6oGM/P4MvCxFCkQoTYYcO1xzvbCIkeYR6ZFzl7kbPl0YLIQUrx1NP7qdLtKEOBSGEfIKJsEPTe92UIkvq7F0pV8XVHWq2Gzn0tDBXSTyXT92xm7RhtxAhFIEwEXboTOO5N/a939m7+DJeXJ68Zl9TIEIKWw/mkYki9oXjwsiblIoQ4jxMhB3qGZe9aPiDPtzY7boEeRa3ZjcTAJ+MhsNN1ORCeyOH3pAihKIBJkJ3fizZdNbtoqMuiROFikxuJUIAiBeyP44xDkkg8tfb99ZizxAhFDEwEbrTNyE3VZ7i+ToEAAA8El7Ip94dRU7ZjIvOIIQiBiZCd7orM47VnTTZzT7ce359lU3n7daR0WRyOvnHFN7qC8xDv3NoxBBCKHJhIvSg1lBvpa0+3Jg8Oo4vb1nB7vhHpae/LDfV+VJPJOouJ4pu4n1zjqkxhToUhBDyBBOhB5NyrqcZX3o2rdfgzrk1hSelLhVxaNEZBR9mZJLLcaI9QijsYSL0gAX2nYOfmH16OuokUgkyJqrrj2pteg49LL23N/nxaYbBcTMIofCGidADAogXrnpCxBN1sR6+lIofoKj+w/X8QqvGxkZdxhiWQMQIoKgq2r4uhFCUwUTomclufnTrMyx09Rd6yhhV1Z5GlnZRT8W2en15lzqd4emeXuQnp/HpKEIorGEi9EzME715zUsEdHXXPUmyqNe8NJfVdJ+aLE8Xt3yIoh7U3Bxy8yWmFofMIITCGCZCrzSYGj86vLzr9cRkSwnSVSYkwJEgG45rj390wdJk63pb4SBGAFMzyBVnsVOIEApfmAi9ohQpb+5xQyBqLt9c23oETVyeXNlLduTtcxXb6mlzNOSPe3uTH52KuvefCKEogonQK3ySJyD5+yoPdr2q5jP6i7/UOI4bjmnrDmt4Ysp5liCJtGsS+j2YZaw2/7m4uPSnaqs2sgeajkwk5HzYgUNmEELhChOht6yMjST88O2KyZFm3KgGANrCnF9flX1LCkG1fVgqUQt73pY26PEclgFjdcQPormrJw6ZQQiFL0yE3kqRJQ1U9yvp/BrcbTjfEV78pUbZSxaTLe3oSqGSnzUlSdlT5vioPW+I0HE0t/cgfyln6iI+oSOEohMmwk6o0FWeqDvtl6q0F4z1RzRZk7zd+Jexs42n9F0euBoaMQK4OYP8qgQ7hQihcMQLdQCRJCsmPSsm/ULzxSxlRherqtxZnzk5iSelPF8KAAAkj8i8Se04pi0MJYywv2DuzyWv/9X+3klmkIoYqCIGqYghCUSS2PONCCEUaBH2+zTkbLRtQ8mvDNvVzk3WzcmJg5W+3XtuXWX5bxG2bOnIREJzO3/TDdTM7oTBzr57gh6ywW7G3SkQQmEAE2Hn8Cn+o0Pvrzc12n1aidtJGMv3+Tln5k1JlTsbjDURthM8SUDPGGJWd/LVoVThRN4gFXxWjA9LEUKhh4nQF2tP/1RvaghV6wIFr9t1Cee+r4zQsTMOL+ZTS48yFuwUIoRCDROhL/6Wf6dKFKu16kIVQMoYFWNnaw64XsI7IuTHE/3i4AvcpwkhFGqYCH206cK243WnQtY8Adkzkkt/rrEZwqVLZTfS+rOdmyHx0mBqyVHGiqkQIRRSmAh9NDlnwqjUYVpLyDqFsjRxxg2JYZJGmk7pjv+3rHqTtlNPawfHE3lKwM17EUKhhYnQdxc0ZV8dXx3CAJJGxglj+W0KWYbt6taGLNAWb5MTbWHOrqk8t7Yqe1YSP4YyN1o71dTz+dTiI4yVAX0FblGBEAoNnEfou6yY9AcH3623GmSCDleHCQ6WYR0L1lzcVFu5sx4A5BkSRaZEkSWRZ0g6O+nQbqZLVl3KvSMdAGgLQ1sYgaLDn5NzaysJihi0KMdO2DLmq0Rxgk61NSKR6BUD6wubsw/WDnm6Z4SuGIAQimjYI+wShmVe2fu2he5cN8i/yn+razqtdxyrhyqHPt1ryNO9Uq5SMTa2bHNd6cYaL+uhrUzDcS0A8MSUIwsCQNNp3V/vnDfVdThVI2dmao9ZqZTI9x+kFwdTH1TxWQDtBYPPlSCEkM+wR9glJEG+MvYZK221MXY+GZpvZsrVKvJ/y3aLVC0dsrg+8rg+8k7VU723UXfRpOqraF0YPyCGsbLH3r+Qd3eGrFvLSjCMnb3wY3X2tGQggORd0YmjLYzdSLd/YOvGyERCkCy8KI3l7W3WSyQX9Wy5AfgkLOrXKrmygJ1FhFCAYI/QD5Yf+66ksauLcfuMEpDt969og6U9vDVk7Oylovpu1yW0P5U4VJkzM/XEJxebS1r6nSSPUA+PdZmZNOcMujKjV3EDAICx2gIAzw2iHtLIq49qn9tv31TBaqzsO8eZvbUtMbMMe25tZE+aRAiFM0yEfrBw4O158T3N9jDdXsFupk9+dtH9NTV/NMrTJdIUkcuzcXny3DvTi7+uaC5uyYWy1A6vjB8Q4yIGI139RxNjvzKbsVD1eyNtYcYkEZfuFXXrLl6TYfx6HPXqUOqlweST+1tmhhAkYayxVO4K2QoGCKHohonQP/ZXHfq++OdQR+EaT0T1WZjp5gKWZiuK6rsVuOgOOimyJH3vz/R52qKl2VZ7oPnAy8Xlm2vtzkoIyJ6e7BjLQxLQ7boEgaLlmer8HmSDBTaWtyTOHnNSy7fWOUeWam2+RYEQQi5gIvSPYcn58/rcEuoofFTzZ7NELXS+AuyINFmUkO+it9cGY2Nq9rVd8kaaIur/96x+D2ZZmm0Hlpw5t67K0tw2m8XkSBVZEscxRcArQ8h//0nrKsyMjRHFCbKnJxd/VUFbmN9r2Pz1dsyFCCF/wUToNyfrz/z3wMehjqJDVp1dc9b1sExhDC/jRrW/GiIo4uKmWlNty0DT1o9DxYnCnJmpg//VgyciK3d6eNR5cwYp58O2QwZTnRUA4gfExGRLDn9XectWe4oEnj8YkCV1GFswZvcHpxWEkJcwEfpNb1WPh4fcG+ooOmTT2Yu/Lm/7lg4AAGJz5bI0v+0NSJBEYn5M7YFmx8fSn6r1l654e8qX8zJuVGfd7GJTYruJLttU6/z45nDqH6YYnrrlfWTMDcnnzxhfjzdtKOB9d4450uDn8TPGasufL58p31Ln5YoE5gbr6S/LdBc7vRRAzZ/NdYeaOx8gQiggMBH6DUkQf9We/OlsYagDcU2aIpKnS2r+aAxCWwlDlLUHmx3jPLtPTe5oZE17lJCMzZU5Pw5PJPrFEh+dYgDAZIepO5hzN2bcdp08Tgj/l0/ev8vuSFjn1lZ21Nn1nlVrP/npxW4FCfpLJqvW7s0tAjkvJltW/HX5X+9daDyh835ca/KouIRBypp9TfVHNL5H7Cd2E31mZYXz+ORnFzXncEIn4hZMhP6Urkgdlz461FF0qFtBQkVRfeupFLoyk8dHlD6QJot4Eqrl92ln5v8RJCHPaHlNWH9EU/+X9rVh5KtH6SYLzNtOZ8iIJ0cLHWvojDtV081o/fwMAwBxefLibyou/FDlsr/rDdrCnPykNGlkbMoYVe4d6UIlHwCAhY5ym91IAwApIJOvihv8VI+Uq+LKNtcefPXM+Q1VjgsYO3vm2wq3XyoI4wQXN9WGfFoIJSQzJ7X0zikBGddHcXZN5dH/nqs/2rmVY33G0qzuYiem3CDkd5gI/SlWpKzS15xpPBfqQFyTdRNLkkR/vXfh7PeVjhJpkjCub+fm3XspcYjy4q81Pv8mZRm2dGONQM7rrSQmpJHDfrBrbeyXY/+/vTsPbKLKHwD+fTO5mqRN0ja90vtuablBDjmkVBGPqih4gLsq/hS8VtHVXRBFQRR1XfHaVTxAFFm5FZBTuRXKTQsttPRMeiRp7nNm3u+P1FLatLSQNqV9n7/ayXT6JpnMd971fZfmSybdHTVvknhePqt1gCIjcPBLyU4jc+L9C5bKq8lZWra5Rhorjs65bNxs/XFjzSHvFeia3/WG4saZJIhCoQNlA59PSpseEzZE7tlI0Ug1NrTFX7FOrnBZOeNo7N2Up0j4Ylp7skOVQuMF61WHea/0BWZP2EYUakqhh2gUMUIx5OWU6Byleq82f3FxU9KidmAOWyrs6r26iu11hmJLxxPVNtGdNrXzqtvClG+pveJcWIK4aiSzjI85GEeQMOjK+/lJwu3h1hpn0+BMSkB1NjtoBykHyRGFri4dTMlaNWaxUMH3lHPBEOq+XeyaHB6/+WMbggHB6IEk6pUj7LIxNE9Mpz8cU3/cWLCsPO6WsIhRwQDA2FlrtUOWfOVMsHGTw2lBy4fC0IFBbQXy6AlepppcNuwWgeTPBmH1Pp00OiAoQVy6TiMI4vFEdNNeMbnKss21oQNkbb1R2pNGc5ktIS/SUm2XRIkoHu19PwBrtaMplYEsSRIQJmxrTwCwVNjPr67u93ic95cRhGQFhWQFNZw1W6rsinSp990AAKDhnOXc8gpRsCAwQcwT0RXb651617BX0zxn5DIxrRPVsk7OXG7TnTbFTgrnS2hEo6YqqVeVO+odOpenJYAgugIJhD7WP6yfwWnsCZm4vRJHisSRHe2xuxaCIF7UmJCr+1tRqODixpqsWfGeX+OkaP8dvFZxCgDgjSF05hrmYC0eFY4AQDlIJkuSNHVxcW7s0Ltk0O4HgQEQNA9OTZruvIyddZuZ9kNLe6cTLDi3vCIwTmyvcw58Pqn5S4qMwPKtdboCU4vMdh6mi7aSdZqsJ+IBQDWuZf3yUvkBAMBlZixVDgDAHC7fWhedE6oaG+o1vjr0rsKvylPuV11xwowiI1CRcYUGg6AE8bDX0i57A//Mh4c5fOHH6szHGsNt/VGDqdxmumhzaF0SVYAiTYou/0xPLS1NfTBaFHrZk5lD66o/bhzycornmIyNpUXU1QVFzGJPDia3leVL2nykIPog0jTqe1tLdmmsHU11TbSmHCwPSpTIUy5VRLxGQQAI5MP7N1AP72HfOcntr8EOFgRBPOWgxsmOgiBe+HAFAACG6j3a1k12+kJz1W/aK5bHXG4//clFz+jQ0vUah65zOdaD+wUOejGZ4qG0GTFUqzOJyVVW7fJSBnu989w3FWkPRTdP94M53KKSWvhVOefEAKBIlybfF5V8X1TKNNWA5xJ1p83Ve7wc1m1hCj4vj705LDjzmprEdadNnkZdWki1fIz4M0ghCjVFQcbO6s6YRCGC5HujRizM6P90Qkyukhdw2R/K06SVu+pb/KOyzTWq8SG8P+OWeq/OE+87i7GzZ7+pAABrtePkByVsz1jIk+ghEMbXX8t7QkLC7t27ExISvL5aU1MTHh6OkD8bUjy3q6tsGbw+OZ1Oq9UaHBzsm6MZ3I0jVjpg7UVuXy0+VIvPNOABwWhCFFowhG6efhVzuGSdxlJl7zczji9t1gqCgWNxi7zhXjWcsxR/XxU2RNZQZBk0J/mKyV07AYOjwdWigdptYU5+WBpzszJ8mKL59vOrq4MSxI3RHQAAODdntpn5fL5YLG5x2KZTYxysJ1axTu7w6+eixobE3dqJaaOWaoex2KK66bIqKcdgt5npVHb1K2LsbP5bxYNeSG46rLncdm5F5ZBXUii+Dx7Zm2qExd9V8YN4CXe01x7bEbW1tUqlkqKupmxNS6ddvzgGs3aWH9jdzYoul8tsNoeEXGWDk1ekRtglFh34oNqs8XcprmMdj4IAMCWB+vcI+o88Xv10/uJh9P5avODYZdPtEYWS740KTg889fFFm8ZRul7jbHADQOvVM9qiSJdmPhZbl29Ivk/lyygIAAg8UbBp8iJm8bF3L4QNlbeIggAQeWNI2eZat4Vpqhe2GSGaTg3DuW8qPdtoITViYUanoiAAiIL5YcPkLTZSPOTbKAgAvAA6YkRw1e5LlcLqPbq4SeFez9GTZuGKdKdMTVM2mz64hLyIuiMGa7XfkgMbii35i4prDnbHXKauU3u4ofZIL5kOSwJhl5g3+oXowCh/l6LPEfNgXCRaN5G38gLeUN6y7St2UljUjcHH3y/h3BxP3OkuosA48eBXUpvGGfnc6Y8ven5ANBr8YnLsLWGt95GqRGGD5Rc31RT/UNXB4aaAIOvJ+Eu/dT6K8wLo5tVoW62zaeCrz6nGhdSfMDbN40x9MDpsaMsYDACYxWf+c/GKk0drDulL1mvEES07xflSXvxt4Rd+rG5/VLOp1Hr604ucrxtR3RamZK0m7tbw6j3ayu11V/6DnipyZHDUGN+0AHWKrcbprO3QTN+OI4Gwqyw6+C+rm8yO8oNgIXx3E/3kfrbM3PI+F3ljyJB/piRPVXkyfQNAhaUTXQNdOsIi++lLTf3tNDfFTgozlljt9a5r7OTrLMxil4nBLD73TcW1py9oC1/KCx+qaKrDUTzv3QuIRkn3RF1Yo25nSknljvqqX7X9n07wuqZK+HAFxac0B7xPouUYfPGnmnMrKiNHBzd167otvrn58qW8wS8nhw2V938mUXfGXLJO0yIesy7uwo9qq6aHrmZzCWq7QaIrlW+st9f6eC10Egi7yhOD/irhd1XtgWjfyDA0dyB97y62ddWlqTcOA3x4hkv7kTnT0CO6yTvYY0QLqdQHozMfje3me5DutOnc8orKXfWiUIHXMa6+EndbuGp8qLncxtjbq3cG9wsUhwurWg2uAQDAULpeoztlHPBMYtNS1S0hSLo3iifx8sBhqXac+FeJU+8a9FJK05pi9npn5U5v/6vDdKdN9ccbK/Gez5ov5WXPTgCAFiN3aD7FC6ALl5W7jNeaWp5jcM0hvVXt05iK4eJGTdMaMqaLtqtelOYq6M6YWAcrz/bxrZUEwq4SGhC8smBNrfWavjzEVXumH5UiQ88e8v4VNbnhvl3sygvcU5nUq/nX2QBCWZLksiE/3SJ0gIx1cerfdElTurbN39O16TQyjf24bUu8O1KzX9eU3r2J5qDeqnFkP5XY/jgOcbjQM8DYoXM19RdqTxgL/lsWkxOa/pfY5g0AAUph4l2RV3E6TQnW5alSeUrLmTy0iGpaiax0vcahdwEAIIi/PTzqxpCCL8pZx1VenIyVrdxel/9mUV2+oXhVlQ+TBFXuqrdUO5o6F+qPGao7MPS6U9wWRnfGS44FzOHyzbUxtyp9PgyRBMIuNDxykFLsy6FNRKd8cSN9oAZ/U9zyVnJCh4esZ8IDYP8dvIVD6aNa/Eddj6gU9mgIEm6PiJ0U1qlxTFcttH9QW8tENxHK+TE3h11Yo/bc5ZtCTsQIRb//i6dFHb25MXbWZW5s9gxKlAyak6Qc4qVj0sPZ4DZdvHKXB2axscR67puK0580dv3SQqr9x5eYXKVIcan+qropNChRcnZ5RQdT6pSsu9SaWr6lNn9xsdPgzn4qof8ziRmPxF4xcmAOl66/8vg+c5lNs0+X9lB00wGjJyhrfte3X33vrMod9UUrKlu/z7V/NAhkfFmq71vayIT6LpQanHRYfUwqkGaGpvq7LH2RlA9rJtKjf2JePcqlySBVhtJkyMXBu6fYpSPp+5Mab5TzB1Nz89mdk8l34QrkaVJ5antZZrpf5Ohgz2REzOHCZRWeJAyI7tzcqeZLr7TOg9OC0+A+t7xi4AvJXvd06Fw1vzeYy2yWKntAqCD8huDw4W3G1BZah8nEuyLOfVNZvqU2vo2ZHg6d6/wP1VlPxiMaJdwegf4cAi1LkkSNCWmqELeTPYpjMEUjQIAopBwi98y6sakd0lgvyRYYO1u0sip5mkogu/QwJFTwQ7KC1Ht1LYd3YWgxqIriUx0cpC1U8FPujz73TUX20wkByj8TWWCo/k2X9nBMR47QWeTL37WkAmmk1GdL/RGdlSFHuhn8CgsuMkKxEZ8z4Bo77L2dly6/9IX8awr17ilulxrnRF3f87q6Qw97hxCFPMNKEULNB8d2naAEceSo4OLvqzwZf1rgGEzxUEyuMjBO3DQg66ohCqVNj2baaB1lrGzB5+Wq8SGekcDNczXI07w8r+hOmyQqUfOgaC6zFa+qSrk/2jMWOjA2AAAcOlfBsvJBL7aM9JjDRSurgrMCW4/SipmoPPlhqWpcaPNauO6MqXhVVfP53JjDwxeke3IZsk6unfdHNT4UADiWK/i8fMBziY2PCAgGvpBECymXy8cjZYAEwq6WGZpabdaUGsqGRAzwd1n6KAQQJ0VxUrhZ5f0uzqNgwWDqH0fYP/I69rxK9Ezd9eFFT1QaPiur2l3PzwIAAAwXN9XE3x6OaCQOF3qd93LVKAElEFAAgFlsq3U2NRdzDC78qjykf1DEyI5OYKB4qCmVD2Zxxba62sMNSfdEtZgRJA4XRoxQlG7QpF9e93IZGUEQz+syoqIQgSJdqjmga562PiQ7aGRWZvMPxfOU4Pm58Mvy7FkJ7X9k4cMUTr27eo8u/rbGusS1P1u0hfQRdjkH6xTzfbbsLdEVpiVRDAebWk09JIjWPBU19V6dQ92YliF0UJtp033FrnVdmrWCofi7KmGwIH5yJ1qbFBmBnkBo1ThOfFBiq3EOmpMc0t/LAOCYXKWlyt5w1tx8o1DBT5mmamtsc8xEpae9tOynmks5CC/ft3m7aPZs71Hwwhp189FPsTeHec7RdNHWweWyrw4JhF0uSR6fIIs9WnPS3wUh2oQA3hxKz83nuvK7RvQeAhk/eapK+1tjZAqMDejqfGnicGHU2MaRd9V7tW4rkzJNdRXR117vPPNZWdS4kIxHY9saVUvxqeR7o0rWajzJBBrHsrYrIEzoaaOOHBPSiZRDGAxFl63zlXBHxKVOQQBAjdHUWGK9iuW9Oo4Ewu5gcVlrrNdxCom+4LYYJBfAdyWNXzYWQ4kJ/6rBBt/3RxC9QXC/wJAb/bPCTGCsOOOR2A4OPGkhQCkc/HJK6+x9LchTpYEJ4ortdQBQtVvLdHimoFDO7/gzAeNgL6xV1x5uaNpCCymv0T1mYssU7b5F+gi7Q6g45Lak3MPqY0MjB1KIPHz0UG8Nox/8ld1QhouMuMSEI8RIJYYzDXhoKLozjrozFsUHkj5E4pKA2O6YSdLaNeb562CCpMS8CJeRAYDke7tq5igvgO73ePzpT0qFMj5PTAeECbuuF/AKJfHLf+2DMOASQ1n/sH4i3lUua0d0tbERaP4gSiGEVBmVGoQCeAAANgZ2VnM/VeDFJ9iwALR6At18xClB9FZ8Ka8b8jYEKAXpf409+1UFQpD5f/FSVXesltoaCYTdBAF6IPOeClO1xWXJDE3zd3EI7/4vveUDqZgHd8ZRd8YBh+mvirlJv7AH7qBVEhILCcI3guLFSfdG6c+Y/BUFgQTCbtbgMJAEpNcpCsHMNKrBCbf8wu69nRdMKvYE4SOh/YNC+nVrEvkWSH9VtxoQ1i82SLXx/NaWC40T14mX+lOTotHkbYzVx+vAEESf5uNlPjuJ1Ai7G4VomTCoTy1e38u8ewP98G/sQ7+yayfSNAIMcLgOry7lNpRjEQ0xEoiWoFgpipXC/YlUQMe+YQ1OUJAqJkH4CQmE3Y1H0eNjR/9avj9JkRApCbMyNrlQ5u9CEZ2AAL4aS9+xnXlkD6uSwOpSLKJhWiL1080UQlBpgUorrrLijwqwwQXPZ3Wo0eWJ/ewz/agxEeTxiCD8gARC/wgVh8iEgeWmqr2Vhx7t/+DHR5fNHvwoy7F82j8DsolO4VOwJoc3/Tc2BsGGXLp/8KUAlikHzxzgKfH4ll+YJ9Ip8ZW+ZMe0+KcKrtqGD9xBvo8E4Qekj9A/spUZMmFQsiLh0f4PAsD42BspRH19etXp+kKzy3K+odTfBSSuQMqHDbn0oqGXRcHmsoPRjeHUZ2evnA5jbj77/g20nYGNJMcbQfgDCYQ9QpYyHQD+b+DD/UIz6mzaMmMFAHxfuNbf5SKuyetDqCWnWHO768vur8HnjDAznVo4lH75MMeQUEgQ3Y4Ewp6FQihJHp8bP57h2JhAFQB8dPSLBofR3+UirkamHE2IukKlcN5R9s0hlICCyTFIJYFvL5BISBDdjQTCHopH0WNiRgDA3am3KUSyVYXrTtcX+rtQRKctGEz963SblcLNlVjngAf/XCJ48TB6/lHOTiZmEET3IoGwp4sOjAKAW5NyMkLSjmiOH6897e8SEZ2QKkM5UdTHhV7qeRjg1Xx24VCqKUfxcCUapkSfdKBbkSAIHyKB8PogF8p4FB0aEBwbFK2x1BbpLvi7RERHvT6Y+vcZ1tSqUri6hONRcGfcZd/BxcOoJSdZvbPlzgRBdB0SCK8nCfK4kABFnU3L4o6uikL4XYoM3aKiPiq4rJ7HYlhwnFs8rGU6jTQZyouj3jtFPl+C6D5k3tL1Z0BYPwD46tT3kxInREkdyHUtAAAfF0lEQVQj/F0c4speHUSN/omJCIAgAYhoCKDRwTqsEkNOlJepF68PpgasY2akUBnelrmwMfDZWQ4BTFSh7GDU8Rn4eidsqeQ2leMJUejJDPIETBCXkEB4vZoYPzZKGuFkXUJa4O+yEFeQIkNzB9IHa7HZDQ4W7CxndsPSkd6XhVNJ0OJh9LifmVtjqLkDqVRZY7BjOPiymHvzODcyDClF8J9znMmFc6KoUcG8O2ORuI1c7hUWvOYi/qmCO67DOVHU6HA0/yg7JYFS+i3Rf4fU2SEswN+FIPoMEgivV7FB0Q7GOX/f2+/cNJ9kLu35nutYrjWPx9OpqYnU0gLuxp+YW6Kpfw6kTuvxq0e5OClsyKWHhjZ+3OUWvLMabymj552k8uLYpzKpYcrGlzDAzmr8SSF3oJabEk+91J+eEIVENABApRXPy2f/e2MXrvd9jUxuWHSC/bCNBwWC8DmE8fW3DEJCQsLu3bsTEhK8vlpTUxMeHo460Wh0HeMwdrGuClNVanCSf0vidDqtVmtwcLB/i9HLmN3wUQH3wRk2IRAtHkZ7bUo1Go0WLFhVKfyskAsVwexMyuCET89yEh7MzqQeTGqZ483ggowf3Ztv4Q0ObXk0DoONAam/0/ytLuX+fpgrv7+nP6bX1tYqlUqKIu3M3crlcpnN5pCQEB8es6dfakT7KIRKDWUaa53fAyHRFQL58M+B1PNZlIjXXq1fIcAvZlMvZFFbq/CnhaxMgL4eS48K9/4XcgG8OZR+7nd27+285nswHDyyl5Xy4bPRfq6KbSjHFRZ8Wo+z20hfRxC+RZ5lrnuZoWk5cWN+Ld9vc9v9XRaiSwS0GwWbUAhui0Gbb+F9f1ObUdDj0VTKzsCqkksDWV0cTNvN1jvwhjLumNafrUQuDrZVcVMTqc2V119jFXGdIoGwl3CwTpoifSpEh1AIPhpFv3yYs7gBAGwM5G1nGAwbc3mLhtFPHmA5/8Wg3WrcT4EeSaW2VJLEAkQ3IYGwl7g1Mafept14fqu/C0JcH0aGoXGRaPFJ1srAnduZYCFam0MLaXgkleIhWH7eb0FoYzmXF0fdFIlO6TFJLEB0DxIIew+pQDIwLMvfpSCuG+8Moz4/x439mUmVoW/H0zwKAAABfDSKnpvPGlx+KBIG2FSO82KRkIaxEdT2KlIpJLoDGSzTe8iFMrlQ9tHRL6Zl3B0mDvV3cYieTiVBL2TTegdecsNlCW6GhKK8OGr+UbbFTMc1F7kd1Ze1mY6JQNOTffkwfbgOK4SQIkMAMDkGbanE95NBYETXI4Gwt5manhcmDv2t4sDg8P5BwkB/F4fo0f7en2qZ5A0AABYNpTPXuB9LowYEIwC4YMLPHGSrbfBkOsX7M/BxGP5xhJPy4a44n8XCDeXcXXGNBbotFs0/ynKYpsjQUaKLkUDY24RLwgDAzjjEfHGxvkQpDlWIZP4uFNFDeY2CABAshDeG0E8dYHdN5v37DLfkFPtMP+qfA2nB5SFvuBJN+oUJD0Ajw3wTrDaU42/HN1ZDYyQoQoyO1OMbfHRwgmgL6SPsnW5NzOFR9FldMYvZKrO6zFjp7xIR15mZaZSThZhV7nwtPnkP7/XBLaMgAAwORcvH8absZEpMPhhmWmTEFjcMaTbN/7YYtJmMHSW6HgmEvVleyq2hAcG11nqr22p12348t6mtPRmOBYDT9WcPq491YwGJnotC8J8b6RXjeT/m0NGSNutkt8agBYPpydtY3TWP8NxQhvPiLssINTmGzCYkugMJhL3fkIgB/ULTOcylh6QAwNPbXwGAA1WHT9cXMhz7W8UBAPjnnoVWt00qkMTJovX2hiI9We+QgCGhaFL0lZslH0+n7k1Ak39hbMw1/bsN5VyL7sZR4ajcjNU2EguJrkUCYV8RKJBmKzMA4P2cNwAgJkgVKY1wsS6LywIAb4+fL+GLE2Sx4ZKwaovG7LSwmDW5zB0//kfHl3GYtGL1UQuH0ikyNPZn5pNCrs5bgiMWg73dMKmxQbERj4u8LO7SCHKjqa2kUkh0MRII+xzPsk2xQarQgGAxP+D25FsAgGrWIpWtzBwaOfBUXeHmCzsAwM21dwNzMM5vTq8CgFsTcqos6v+d3dC1pSd6JATwzVh6wRD6jzqcvsadu5X5soj7ow5/cY6bfYAdtYmRr3DH/eB+9xTXVjjcVMHdGkPxW92QPJMourr8RB9HAiHh3aDw7Acy76kwVf37yH+gVTjEgHX2hl9Kd4t4wv7KfgCQLE8IEQWPiRnpn+IS/saj4LYYtGI8rX6QPyuD2l6NZx1gD9bhdDl6ezhd/SB/3x28P+px6o/MsiKOadV2sKHs0sSJ5iZFU7vUnKu72hrKzCTo9kVk+gTRntig6BeGz3Kyrrl7Fr03YUG+5sTQyIFrzv0UKg4eqRrmmac4OKK/Z2cJX6yQKv51+LNZgx8J4PXshV+JLiOi4Z546p74ltuDZGhNDn2kHv/jCPveKW5WBhUiAiENMgHiMBysxT/meHkuV4ogQ4721WDPElTHdfiHEu64DueqqDvjUJrssthZYcE71Ti/HrPNwlkQH57pR8VKr9DZ6WDh74fZTwq5f91Ad2rxSKIXIIGQuAIa0TRNL7npNQAo0J7LDsu8M+UWPs1HgEaphrXYGQG6N/0OEgWJtgxTop2TeTuq8dqLnIUBFwsGF8dw8FAy1dY6iJNjqK+KuL0a+KEUcximJaJZGdRONc7dwgXwIC8ODQhGB+vwzmpscOEJUdSoMCRslhKn1IwHr2ceTqH+OZAObePCLDTgB3az6XJ04m7etN1snQMvHNrWHEuiFyIL8xK+0Xxh3l3l+2hEjY8d7e9C9QlGo5HP54vFYn8XpKsc1eJ7drJTE9C0JGro5YsJH9fhTeX4pB6PCkcTo9CAEO9f+1o7LDzO/lDKPduPfj6rZcT97znu1Xx28TD6sTQKAHROuG0b0z8YfTaabj8YkoV5/aIrFuYlgZDwjeaBUGdvCBIG8inS3tAden0g9Nyhrv37XGrG849yP1dwkWIUIoQQEQoRgtqG6+ywagLdvJXVysCUnYyEh767iRa1vbgZCYR+0RWBkHyEhO+FBCgsLsvr+5cAwIWG0rZWDLYzDrWlBgB+urCtnaPZGUdXFJK4XiBfREEASAxEK8fTpdP46ybSi4fRj6Si0eEoL446dCevRV+jhAc/3cwT0ZC7lVldytW3ugCNLthQzi08G/B9Ca4h62Ff/8gzO9ElFCL5Szc8DQAHqo7cnTr5TP05q9t6Q9SQRQc/mDvq+U+PfTUmZmRIgGJX2d4ZWVNpRLOY3VC8dVzsqNCA4BaHWnjg/X+M/NvXp79/fMAMEel9JK5NsBCChZ6w11545VPw7Xh6WRH3fQl+Yr87MRBNVKEblOiEHu+sxgUNeGQYypbA2jL87O/uaAmaGIVyVdSEqMu6J5s7psV6J5jc2M2B0QUchrAASJej5CDUOncd0c1I0yjhG82bRlurs2mtLmuCPK7MWBkvi3FzTOuG06M1JweF968wVUUHRvEoGgA+O/b1w9nTxPwABOh8Q2mKIrFIdyE1JAm1fQt748B7fxv6xMHqI1HS8OywTABoZ+feodc3jfodw8Ef9XhnNT5czw0IRhNV1OhwJKQbm0YxovLr8U413l7FnWnAeXHUtEQqJwp5luk4qcc/lHCrS7GAghgpBPERjwK5AABAY4MiI66wYJUEpclAwrt0oSIE9yWgKQlk4Q0vSB9hIxIIe6D2A2HH/ef4Nw9mTikxlA0Kzy4xlMXLYmjU+IzNYfzx0WWzBz/qCZPNcRj/47c3377pVbPTEiQM1FhqAwXSSnP17vL9Tw1+1M44evFAVhII/aV1H6Hahn8sxatLuQsmfEs0la/FLhamJaL7k6j+wd7vSG4OSs242Igd7KWNNgY+KuAoBIuH0Z55I83pnCDjA89bPZLFcLAWp8uR8qqu93MGLObBFaea+BcJhI1IIOyBfBUIPd4+9OGTg/8qF3pZQMrNMS//uuBfOW+uPPNjekhKvCzm0+Nfzx/9oslpbr3+opt1M5hdsH/J2+Pnt6iGchhfNJZvLN76wvBZDMe2Dq7XCxII/aWdwTLlFry5Ag9VouHKq7wRYYAfS7l5R7l4KSwaSot5cKAWH6zFB+twjQ1TCMZEoIlR1EQV6qdAZjdsq+J+qsBbKrlIMaq34/dH0A8mdaLJ1cbAwuPs5+c4IY3WTqRH9OClr0ggbEQCYQ/k20DYPgfjEPFETtZFI5pClIt1iXjCdvbHgAHghV2vvnvTAhtjCxIEri36OSRAcWP0CJ1dL+QJ3v/j0zfH/qP5n6gtNQE8EYu59cWbHx8wY8WZ1fel5xmdJqvbliSP79Kz6ywSCP2lG0aNujn4qph74xgn5sGocDQqHI0OR5lypHfCbjW3U413VmMbgx0sjApHd8ZSd8QilQTla/HMvWy0BD67kY5pe+WQJpvKued+50aHo/duoI9p8SN7mQ+8xVFfDd+9RiQQNiKBsAfqzkB4dTzVvtf3L3lmyOOBAoknJ4DnJU8Cudf2vf3WuHmrCtdNzcg7UHU4UCDtF5pWa62PCVKdqD2dpcw8VVfAp3kpiqQ6mzY2SNXO/zpTfy4zNFVr11vdtgRZrNpSEyWNMDiNQlrIYa7CVJURkuoJ59d+XiQQ+ku3TZ/A7YafMjMOFaEWkyPdHCw5xX14hl0whB4djoqNuNgIRUZcZMQ0ghgJipZArBRFiWHFeXzBhD8ZTd/0Z8bzMw04bzv7YDJ6Y0jjRMoKC/7mPP6mmLMyeEIUNTEKTVShuGYtqDV2qLJipQji2m1WVdtwkRGKjbjYiM1uSJOhNBlKk0FCIPLa0uvR4IQaO86QNx6ZBMJGJBD2QD0/EF5Rg8OoEMkOa471V/Zrp4pZqC0uNVy8PfkWz/6lhvJEeVy+5oRMFBQuVi7546OFY/+54szqvJRb1ZYavd0wOnr4a/veWTDm5VWF6waEZUVKw3aU7Zmanjdn9/y3x89HgK6xVdaHgXBf5SE+zR8RNfTaD9UX9Px5hGcN+Mn9bL0D0uUoVQapssakdBUWXGWFSiuusMCIMPRCNtVi5Gq9A+7ZyUQEoLvj0dfF3HEtvj+JeiSVUorAUw3dpeZkAhQlhmorVFqxTADRElRuxnlx1NxBVGLgZbffPRr86Vnul0pOSEO6HKXJUKoMSXhQbMJFBlxkBI0Np8tRThSaqKLGRiAxDwDA7IZN5dzqUry3hhPRcEMY9eogamgo6opACPg6FB8fX1pa2tarOTk5TqezO8tDYIz379///PPP+7sU3afKpP73kf9gjBcf+pDluPP60nJjFcbY7rZ38Agc5jDGC/YtqbdqPT/b3Y5yYyXGeEPxFrvb0eAw6O2GFn/lZhmj04QxdrFuz5a33npr/fr1V30iLMdhjD84/B+93VBt1pic5kpTdZVJfdUH7Dtuv/32hoYGf5eiqzgY/Nc9zM1b3KsusHam5ascxid03K5qrtjANb2qd+DXjjKh37r+8htTbODMLvxZIZu91p35o/vjAlbraO9/Hazl3jjGjv3JLf3GNf5n913bGdly1x3bmJXnWbML2xn8UQEb8737tl/cK/adnT17tm9PtpsCoclkmjt37l133TVv3jyTydTO9rb2bK79QCgQCGw2m89PgWjfxo0bc3Jy/F2K64+bZTDGn59YcUR9vN6q/frU9xjjnRf3cJjbV/n7b+UH3Czz+r4lGON/Hf6szFBRUF/k2WfWLy9hjDdf2HHfiw/8++MP3/39Y89xaix1JQ1lW0t2YYw3Fm/FGJ+oPVNmqDA6TJ8c/RJjvGD/u1qb/qjm5I9nN7Ec++yOf2KMayx1npJgjH8t339eX+pi3Z7w3JZ6m85z/D/URx2M0+y0aG36a39DGI5hOMbzw7UfrUspFIra2lp/l6LHaXDiBcdY5bcuxQrXlJ3MrmquvcuoFYsbb67glhez+laB08HgTwvZsK/NGfc+67vyYtxtgfCLL75YunSp0+lcunTpsmXL2tne1p7NkUDYA5FAeC3Ytu8VLMfVWOowxna3vXVsMDst0x+d8dHHH1UYqzDGanONk3E2OAylDWUY403nf8EYn647W2ooZzm21FCOMba57Rzm7G672WnBGDsY780n3xesPVB12O52WFzWpo2e0Hig6vD2i7+yHHuo+gjGePXZDXa3PV9zYkvJTozxO4eWYozP60vNTovRYTqvL8EY76k4iDGuNmvqrVqMsc6mxxiXG6tcjKvarMnXnMAYv33oQ4zxt6f/d7DqSJ21fv7etzHGG4q3OBinxWW1ujr3pfYEcpPTrLHUtv8OXzUSCNthdOFKi+/fc4zxLzt33zBylG+P2U2ZZfbv3//GG28IBIK8vLz58+c/9thjbW1va8/mOI4rLCw0Go1NWxBCSqWy6VeNRiMS9dp5Yz2TXq93Op1qtdrfBemd1MY231in2WEymmgLUlvUAKA1aQFACHy1TT1EnK1Wq4MhCNxQY60RAk9tvew4JjB6PyjAGNlwClG7z+3ROvQTo8Z+cOa/z2c98c35HyZEjQkTBrshqEZTEwtRarX6xqBh+jp9JCgjRcpqdfW4kJFqtXpv1YFBIdkAUNBQJI4SnakqTKbjjuvO8Clemizpk7Nf/63f/20s2zwuYiQA1Nnq1Jx6bPAItVo9IXg0ALgNrscTp6vVarfFpa2tP1R3FGNuRNiQr4pXPZ42/ZjudEpQAsuxeqchMSiu2FiaKks8qS+QC2QhQsWq0vWPp03/d8Hnf0mZVmfX1thqx0WOevXo228OeWWP5mCMRBUhDjuqPTkmYsRZQ3FKUGK9Q8dgNkYStaH8l7viJv1RfyxWopLwxWcaikaFDd1RvWdC1I2l5nI3x2TKUzeUb70r7tYi44XwgDAQoMMXjw5mBhypPz5MOajSqnZz7sTAuGO6U4ND+qtttXJBEAKkdzaoJJEXTGXJQfEXzRU0RUeLI/93cdP9iXcVNBRFS6ICeCI7Y5cJgmyMXcwLYDgGEKIR5WCcATyRk3XyKT4GzHCskBZ43afBaQjkS62MzeAyxklj9tb8PjZiRIm5TEQJI8Thv9fljw4ffs5wPk4agwEbXaZIcXi1VaOSRDpYJ4/itfhfbs5tY+wKodxTZqPLRFO0mBYb3SaFQOZknXxKgAGzmBVQ/CqrJloSedFcEciXygSBJ/WFQ0MHnDeVxkpUbo45UWsPE4WWmMuSAuPr7FohLZTwxVVWdbw0psh4ITEwTuvQ652Gfoq01aUbpiXeVWGtlvLEcoHMwTrFvAAH6xTSAhZzLMcKaYGnPGd1BazA3fFbTVhYGI93hUjXTYNl7rjjjjVr1giFQqfTed99923atKmt7W3t2dykSZN27Nhx2Wkg1NR3arfbAwICuvqMiBZYlmUYRihsbxoD0RXcbjdC6Ipf9WvEkwsYg4sSUN23SG4riEb8UJGr1i5OCXJW2ZCA4ssF9nJLYP9g8ym9MFKMGc6ldfJkfMbg8noEgVLEWhnAIFSJbRdMkky5rcjEVwiQgHKqbZ7jBCQEurUOjuVEkWJbiVnaT24913IfcWKgs87hsNmDEhT2ErM0S2EpMAjDRBjAVWtvvg9gLIwQ20pM0iyFpaBBoAwAClw1dnFykO2CSZwc5FTbgELCMJGt1ByYrTCfbvCciFvvlKTLLQUNnn0QjfghQnuZxfs+njeET/GDBfayP9+QKDF2ca4GpyRNZi00iFOCHJVWSkg3vmme43jbhxbStEzgqPB+HEmqzF5habGPSCVmHSxjckuSgyxnDZI0mb3MQgXQvEC+o9LauE+0hLUxjPmyfegAmg7kOyqtklSZtdgoipUwJjdnYwLiA63FRmmmwlpk4MkFlJBuevOFMWJ7vZVydHQ45M6dO7Ozs9vfp5tqhBhjzzBOjDHHce1sb2vP5n755ZfuKDRBEATRB3TTwN+QkJC6ujoA0Gq1oaGh7Wxva0+CIAiC6ArdFAhHjBixbds2jPG2bdtGjRoFACdPnvS6vfUWgiAIgug63RQIZ8yYUVpa+sADD5SVlT300EMA8OKLL3rd3noLQRAEQXSd6zKzDEEQBEH4Su9ZmNdsNr/zzjsFBQVZWVl///vfAwNbLkRA+Na+ffuWL1+u1WoTEhLmzJkTHR0NAM8+++zZs2c9O9x2221/+9vf/FrGXqj1O0yu/G6Qm5vbYktGRga51Lsay7IzZ878+uuvwdsd3odXfu+pES5btsxutz/xxBP//e9/xWKx1wmIhK9oNJonnnhiyZIlCQkJGzduPHDgwIcffogxnjJlyrJlyzzTV2iaFggE/i5pr+L1HSZXfjew2+1NP69evdrtdm/dupVc6l1q3bp1u3fvLioq8kyWa32d+/DK77npYjtr//79eXl5npn4+/bt83dxejmNRjNhwoT09HShUHjzzTdXVlYCgE6nY1l27ty5U6dOXbx4sdVq9Xcxexuv7zC58rtBwJ9qamoKCwvz8vLIpd7VEhMTp0+f3vRr6+vch1d+7wmEOp0uPDwcAMLDw/V6vb+L08sNHjzY0xbEsuzy5cvHjx8PAHq9PiUlZc6cOd99951EIvn000/9XMpex+s7TK78buN2u99///2nnnrKYDCQS72rDRw4cMSIEU2/tr7OfXjl954+wo7MxCd8Kz8/f9myZUOHDn3kkUcAIDU19b333vO8NHPmzJkzZ/q1dL2Q13eYXPndZs2aNenp6XFxcQBALvVudnXZVzqo99QIyUz87oQx/vzzz7/77rt58+bNnDmTpmkAKC4uLigo8OzA5/P5fH67xyA6zes7TK787sGy7M8//3z33XcDudT9oUuzr/SeQEhm4nenU6dOHTp06M033wwJCbHb7Z6hBA6H4/XXXy8vL3e73StXrhw9erS/i9nbeH2HyZXfPU6cOKFUKlUqFZBL3R+6NPtK7xk1arFYFi9eXFJSkpKS8sorr0gkEn+XqDdbsWLFt99+23zLjh07MMYbN25ct26d1WodPnz4008/TT4F3/L6DpMrv3ssXrw4Ojp6xowZ0MYH4e8C9k65ubmeUaOtr3MfXvm9JxASBEEQxFXoPU2jBEEQBHEVSCAkCIIg+jQSCAmCIIg+jQRCgiAIok8jgZAgCILo00ggJAiCIPo0EggJgiCIPq335BoliOtO61XuPDwziH37j7788svY2FjfHpYgegcSCAnCn15++WV/F4Eg+joSCAnCnyZOnOjvIhBEX0cCIUH0RBUVFY899tiqVauWLl16+vRppVJ53333NW9K/e2331avXl1VVRUTEzN16lTPkpAe+/fv//777ysrK+Pj46dMmeJ5yel0fvzxx/n5+VqtNjU19dlnn42PjwcAjUbzxRdfnDp1yul0pqamzpo1Kzk5uZtPliD8iwyWIYie68UXXwwLC3v66afT09OXLFmyZ88ez/Y9e/YsWrQoOzt7zpw5WVlZixYt2rt3r+el33///c033xw0aNBLL72UkJCwaNEiT4/ja6+9hjF+9tlnZ8+ebTAY3n33XQDAGM+dO9dsNj/88MOzZ88WCATz588nixoSfQ2pERKEP3kdL9M0WGbs2LGPPvooAOTk5IjF4lWrVo0bNw4AVq5cOX369L/85S8AMH78eLFYvHLlyrFjxwLAihUrHn744YceeggAxowZU11dvX37dgAYPnz4M8884zmsSqV66aWXAECr1VZWVr777rshISGeQ3366ac2m00qlXb9qRNET0ECIUH405dfftnOq5MmTWr6efLkyWvXrnW5XBjjsrKyN954o+ml3Nzc7777zuVyAcD58+dfffVVz3aE0MKFCxmGueeee5q3nSoUCs+yMzKZTC6Xv/XWW3ffffeAAQMCAwPnzJnj0/MjiOsACYQE4U/tT2lovu52WFgYAOj1es+vnjpc8928vhQQEOD5QaFQtD6+QCB47733vv3223feecfhcGRnZ8+cOTMzM/PqzoUgrlOkj5Agei6tVtviZ4VC4QlpOp2u6SXPzwqFQi6XA4DBYGh6SaPRnDp1CgAQQl7/RVxc3Lx589avX//hhx/KZLK5c+d6apYE0XeQQEgQPde2bduaft68eXNcXJxQKBQKhXFxcc0n3W/fvj0+Pl4oFIpEotjY2N27dze9tHTp0uXLl7d1fIPBMGPGDKvVyuPxMjMzn3vuOYvFYjKZuuh0CKJnIk2jBOFPO3fu9Lo9NTUVADZs2GC1WjMzM0+ePLlly5a5c+d6Xp0+ffpbb71ltVozMjLOnj27bt26pn7BGTNmLF682Gq1pqSkHD9+PD8/f968eZ5KYWsymYym6ddffz03NxdjvHv37tjY2OYtqwTRFyBPnzlBEN2vrRRrAPDll18+9thjn3/++SeffHL+/HmlUjl16tSbb765aYdff/119erV1dXVKpXqgQce8Iwm9di1a9f//ve/6urqyMjIqVOn5ubmtkix5pmk6KlTlpWVffbZZ0VFRQCQlZU1a9YslUrVVSdMED0SCYQE0RM1j1UEQXQp0kdIEARB9GkkEBIEQRB9GmkaJYieyOFwXLhwISsry98FIYjejwRCgiAIok8jTaMEQRBEn0YCIUEQBNGnkUBIEARB9GkkEBIEQRB9GgmEBEEQRJ/2/5mV7A89ELA0AAAAAElFTkSuQmCC"
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "plot([mlp[3,:], mlp[4,:], cnn[3,:], cnn[4,:]],ylim=(0.0,0.03),\n",
    "    labels=[:trnMLP :tstMLP :trnCNN :tstCNN],xlabel=\"Epochs\",ylabel=\"Error\")  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Convolution vs Matrix Multiplication"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "w = reshape([1.0, 2.0, 3.0], (3, 1, 1, 1)) = [1.0; 2.0; 3.0]\n",
      "x = reshape([1.0:7.0...], (7, 1, 1, 1)) = [1.0; 2.0; 3.0; 4.0; 5.0; 6.0; 7.0]\n",
      "y = conv4(w, x) = [10.0; 16.0; 22.0; 28.0; 34.0]\n"
     ]
    }
   ],
   "source": [
    "# Convolution and matrix multiplication can be implemented in terms of each other.\n",
    "# Convolutional networks have no additional representational power, only statistical efficiency.\n",
    "# Our original 1-D example\n",
    "@show w = reshape([1.0,2.0,3.0], (3,1,1,1))\n",
    "@show x = reshape([1.0:7.0...], (7,1,1,1))\n",
    "@show y = conv4(w, x);  # size Y = X - W + 1 = 5 by default"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5×7 Array{Float64,2}:\n",
       " 3.0  2.0  1.0  0.0  0.0  0.0  0.0\n",
       " 0.0  3.0  2.0  1.0  0.0  0.0  0.0\n",
       " 0.0  0.0  3.0  2.0  1.0  0.0  0.0\n",
       " 0.0  0.0  0.0  3.0  2.0  1.0  0.0\n",
       " 0.0  0.0  0.0  0.0  3.0  2.0  1.0"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Convolution as matrix multiplication (1)\n",
    "# Turn w into a (Y,X) sparse matrix\n",
    "w2 = Float64[3 2 1 0 0 0 0; 0 3 2 1 0 0 0; 0 0 3 2 1 0 0; 0 0 0 3 2 1 0; 0 0 0 0 3 2 1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "y2 = w2 * mat(x) = [10.0; 16.0; 22.0; 28.0; 34.0]\n"
     ]
    }
   ],
   "source": [
    "@show y2 = w2 * mat(x);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3×5 Array{Float64,2}:\n",
       " 1.0  2.0  3.0  4.0  5.0\n",
       " 2.0  3.0  4.0  5.0  6.0\n",
       " 3.0  4.0  5.0  6.0  7.0"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Convolution as matrix multiplication (2)\n",
    "# Turn x into a (W,Y) dense matrix (aka the im2col operation)\n",
    "# This is used to speed up convolution with known efficient matmul algorithms\n",
    "x3 = Float64[1 2 3 4 5; 2 3 4 5 6; 3 4 5 6 7]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "w3 = [3.0 2.0 1.0] = [3.0 2.0 1.0]\n",
      "y3 = w3 * x3 = [10.0 16.0 22.0 28.0 34.0]\n"
     ]
    }
   ],
   "source": [
    "@show w3 = [3.0 2.0 1.0]\n",
    "@show y3 = w3 * x3;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2×3 Array{Float64,2}:\n",
       " 1.0  3.0  5.0\n",
       " 2.0  4.0  6.0"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Matrix multiplication as convolution\n",
    "# This could be used to make a fully connected network accept variable sized inputs.\n",
    "w = reshape([1.0:6.0...], (2,3))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3×1 Array{Float64,2}:\n",
       " 1.0\n",
       " 2.0\n",
       " 3.0"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = reshape([1.0:3.0...], (3,1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2×1 Array{Float64,2}:\n",
       " 22.0\n",
       " 28.0"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y = w * x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3×1×1×2 Array{Float64,4}:\n",
       "[:, :, 1, 1] =\n",
       " 1.0\n",
       " 3.0\n",
       " 5.0\n",
       "\n",
       "[:, :, 1, 2] =\n",
       " 2.0\n",
       " 4.0\n",
       " 6.0"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Consider w with size (Y,X)\n",
    "# Treat each of the Y rows of w as a convolution filter\n",
    "w2 = copy(reshape(Array(w)', (3,1,1,2)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3×1×1×1 Array{Float64,4}:\n",
       "[:, :, 1, 1] =\n",
       " 1.0\n",
       " 2.0\n",
       " 3.0"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Reshape x for convolution\n",
    "x2 = reshape(x, (3,1,1,1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1×1×2×1 Array{Float64,4}:\n",
       "[:, :, 1, 1] =\n",
       " 22.0\n",
       "\n",
       "[:, :, 2, 1] =\n",
       " 28.0"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Use conv4 for matrix multiplication\n",
    "y2 = conv4(w2, x2; mode=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "* So there is no difference between the class of functions representable with an MLP vs CNN.\n",
    "* Sparse connections and weight sharing give CNNs more generalization power with images.\n",
    "* Number of parameters in MLP256: (256x784)+256+(10x256)+10 = 203530\n",
    "* Number of parameters in LeNet: (5*5*1*20)+20+(5*5*20*50)+50+(500*800)+500+(10*500)+10 = 431080"
   ]
  }
 ],
 "metadata": {
  "@webio": {
   "lastCommId": null,
   "lastKernelId": null
  },
  "accelerator": "GPU",
  "colab": {
   "collapsed_sections": [],
   "name": "julia.ipynb",
   "provenance": [],
   "version": "0.3.2"
  },
  "kernelspec": {
   "display_name": "Julia 1.3.1",
   "language": "julia",
   "name": "julia-1.3"
  },
  "language_info": {
   "file_extension": ".jl",
   "mimetype": "application/julia",
   "name": "julia",
   "version": "1.3.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
